From 21e39811bd234c6f66ab7644864fcc1b8c316998 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 29 Jul 2012 19:36:50 -0700 Subject: altos/cc1111: Fix serial 0 option 2 pins definitions tx/rx are 4/5, rts/cts are 2/3 Signed-off-by: Keith Packard --- src/cc1111/Makefile.cc1111 | 2 +- src/cc1111/ao_serial.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/cc1111/Makefile.cc1111 b/src/cc1111/Makefile.cc1111 index f7ecce33..bfd444dd 100644 --- a/src/cc1111/Makefile.cc1111 +++ b/src/cc1111/Makefile.cc1111 @@ -2,7 +2,7 @@ CC=sdcc CFLAGS=--model-small --debug --opt-code-speed -DCODESIZE=$(CODESIZE) -CFLAGS += $(PRODUCT_DEF) -I. -I.. -I../core -I../cc1111 -I../driver -I../product +CFLAGS += $(PRODUCT_DEF) -I. -I.. -I../core -I../cc1111 -I../drivers -I../product CODESIZE ?= 0x8000 diff --git a/src/cc1111/ao_serial.c b/src/cc1111/ao_serial.c index 00c85ff3..d90103b0 100644 --- a/src/cc1111/ao_serial.c +++ b/src/cc1111/ao_serial.c @@ -236,9 +236,9 @@ ao_serial_init(void) (P2SEL_PRI3P1_USART0 | P2SEL_PRI0P1_USART0); /* Make the USART pins be controlled by the USART */ - P1SEL |= (1 << 2) | (1 << 3); -#if HAS_SERIAL_0_HW_FLOW P1SEL |= (1 << 5) | (1 << 4); +#if HAS_SERIAL_0_HW_FLOW + P1SEL |= (1 << 3) | (1 << 2); #endif #endif -- cgit v1.2.3 From e4d244eefa4c779cd9c8a91389bf998c54705b72 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 29 Jul 2012 19:42:53 -0700 Subject: altos: Add software AES implementation This is untested Signed-off-by: Keith Packard --- src/aes/ao_aes.c | 390 ++++++++++++++++++++++++ src/aes/ao_aes_int.h | 64 ++++ src/aes/ao_aes_tables.c | 768 +++++++++++++++++++++++++++++++++++++++++++++++ src/aes/ao_aes_tables.h | 10 + src/core/ao_aes.h | 2 + src/core/ao_radio_cmac.c | 8 +- src/stm/Makefile.defs | 2 +- 7 files changed, 1239 insertions(+), 5 deletions(-) create mode 100644 src/aes/ao_aes.c create mode 100644 src/aes/ao_aes_int.h create mode 100644 src/aes/ao_aes_tables.c create mode 100644 src/aes/ao_aes_tables.h (limited to 'src') diff --git a/src/aes/ao_aes.c b/src/aes/ao_aes.c new file mode 100644 index 00000000..4977aaf8 --- /dev/null +++ b/src/aes/ao_aes.c @@ -0,0 +1,390 @@ +/* Copyright (C) 2000-2009 Peter Selinger. + This file is part of ccrypt. It is free software and it is covered + by the GNU general public license. See the file COPYING for details. */ + +/* rijndael.c - optimized version of the Rijndeal cipher */ +/* $Id: rijndael.c 258 2009-08-26 17:46:10Z selinger $ */ + +/* derived from original source: rijndael-alg-ref.c v2.0 August '99 + * Reference ANSI C code for NIST competition + * authors: Paulo Barreto + * Vincent Rijmen + */ + +#include +#include +#include "ao_aes_int.h" + +static const int xshifts[3][2][4] = { + {{0, 1, 2, 3}, + {0, 3, 2, 1}}, + + {{0, 1, 2, 3}, + {0, 5, 4, 3}}, + + {{0, 1, 3, 4}, + {0, 7, 5, 4}}, +}; + +/* Exor corresponding text input and round key input bytes */ +/* the result is written to res, which can be the same as a */ +static inline void xKeyAddition(word32 res[MAXBC], word32 a[MAXBC], + word32 rk[MAXBC], int BC) +{ + int j; + + for (j = 0; j < BC; j++) { + res[j] = a[j] ^ rk[j]; + } +} + +#if 0 /* code included for reference */ + +/* shift rows a, return result in res. This avoids having to copy a + tmp array back to a. res must not be a. */ +static inline void xShiftRow(word32 res[MAXBC], word32 a[MAXBC], int shift[4], + int BC) +{ + word8 (*a8)[4] = (word8 (*)[4]) a; + word8 (*res8)[4] = (word8 (*)[4]) res; + + /* Row 0 remains unchanged + * The other three rows are shifted a variable amount + */ + int i, j; + int s; + + for (j = 0; j < BC; j++) { + res8[j][0] = a8[j][0]; + } + for (i = 1; i < 4; i++) { + s = shift[i]; + for (j = 0; j < BC; j++) { + res8[j][i] = a8[(j + s) % BC][i]; + } + } +} + +static inline void xSubstitution(word32 a[MAXBC], word8 box[256], int BC) +{ + word8 (*a8)[4] = (word8 (*)[4]) a; + + /* Replace every byte of the input by the byte at that place + * in the nonlinear S-box + */ + int i, j; + + for (i = 0; i < 4; i++) { + for (j = 0; j < BC; j++) { + a8[j][i] = box[a[j][i]]; + } + } +} + +#endif /* code included for reference */ + +/* profiling shows that the ccrypt program spends about 50% of its + time in the function xShiftSubst. Splitting the inner "for" + statement into two parts - versus using the expensive "%" modulo + operation, makes this function about 44% faster, thereby making the + entire program about 28% faster. With -O3 optimization, the time + savings are even more dramatic - ccrypt runs between 55% and 65% + faster on most platforms. */ + +/* do ShiftRow and Substitution together. res must not be a. */ +static inline void xShiftSubst(word32 res[MAXBC], word32 a[MAXBC], + int shift[4], int BC, const word8 box[256]) +{ + int i, j; + int s; + word8 (*a8)[4] = (word8 (*)[4]) a; + word8 (*res8)[4] = (word8 (*)[4]) res; + + for (j = 0; j < BC; j++) { + res8[j][0] = box[a8[j][0]]; + } + for (i = 1; i < 4; i++) { + s = shift[i]; + for (j = 0; j < BC - s; j++) { + res8[j][i] = box[a8[(j + s)][i]]; + } + for (j = BC - s; j < BC; j++) { + res8[j][i] = box[a8[(j + s) - BC][i]]; + } + } +} + +#if 0 /* code included for reference */ + +/* Mix the four bytes of every column in a linear way */ +/* the result is written to res, which may equal a */ +static inline void xMixColumn(word32 res[MAXBC], word32 a[MAXBC], int BC) +{ + int j; + word32 b; + word8 (*a8)[4] = (word8 (*)[4]) a; + + for (j = 0; j < BC; j++) { + b = M0[0][a8[j][0]].w32; + b ^= M0[1][a8[j][1]].w32; + b ^= M0[2][a8[j][2]].w32; + b ^= M0[3][a8[j][3]].w32; + res[j] = b; + } +} + +#endif /* code included for reference */ + +/* do MixColumn and KeyAddition together */ +static inline void xMixAdd(word32 res[MAXBC], word32 a[MAXBC], + word32 rk[MAXBC], int BC) +{ + int j; + word32 b; + word8 (*a8)[4] = (word8 (*)[4]) a; + + for (j = 0; j < BC; j++) { + b = M0[0][a8[j][0]].w32; + b ^= M0[1][a8[j][1]].w32; + b ^= M0[2][a8[j][2]].w32; + b ^= M0[3][a8[j][3]].w32; + b ^= rk[j]; + res[j] = b; + } +} + +/* Mix the four bytes of every column in a linear way + * This is the opposite operation of xMixColumn */ +/* the result is written to res, which may equal a */ +static inline void xInvMixColumn(word32 res[MAXBC], word32 a[MAXBC], int BC) +{ + int j; + word32 b; + word8 (*a8)[4] = (word8 (*)[4]) a; + + for (j = 0; j < BC; j++) { + b = M1[0][a8[j][0]].w32; + b ^= M1[1][a8[j][1]].w32; + b ^= M1[2][a8[j][2]].w32; + b ^= M1[3][a8[j][3]].w32; + res[j] = b; + } +} + +#if 0 /* code included for reference */ + +/* do KeyAddition and InvMixColumn together */ +static inline void xAddInvMix(word32 res[MAXBC], word32 a[MAXBC], + word32 rk[MAXBC], int BC) +{ + int j; + word32 b; + word8 (*a8)[4] = (word8 (*)[4]) a; + + for (j = 0; j < BC; j++) { + a[j] = a[j] ^ rk[j]; + b = M1[0][a8[j][0]].w32; + b ^= M1[1][a8[j][1]].w32; + b ^= M1[2][a8[j][2]].w32; + b ^= M1[3][a8[j][3]].w32; + res[j] = b; + } +} + +#endif /* code included for reference */ + +int xrijndaelKeySched(word32 key[], int keyBits, int blockBits, + roundkey *rkk) +{ + /* Calculate the necessary round keys + * The number of calculations depends on keyBits and blockBits */ + int KC, BC, ROUNDS; + int i, j, t, rconpointer = 0; + word8 (*k8)[4] = (word8 (*)[4]) key; + + switch (keyBits) { + case 128: + KC = 4; + break; + case 192: + KC = 6; + break; + case 256: + KC = 8; + break; + default: + return -1; + } + + switch (blockBits) { + case 128: + BC = 4; + break; + case 192: + BC = 6; + break; + case 256: + BC = 8; + break; + default: + return -2; + } + + ROUNDS = KC > BC ? KC + 6 : BC + 6; + + t = 0; + /* copy values into round key array */ + for (j = 0; (j < KC) && (t < (ROUNDS + 1) * BC); j++, t++) + rkk->rk[t] = key[j]; + + while (t < (ROUNDS + 1) * BC) { /* while not enough round key material */ + /* calculate new values */ + for (i = 0; i < 4; i++) { + k8[0][i] ^= xS[k8[KC - 1][(i + 1) % 4]]; + } + k8[0][0] ^= xrcon[rconpointer++]; + + if (KC != 8) { + for (j = 1; j < KC; j++) { + key[j] ^= key[j - 1]; + } + } else { + for (j = 1; j < 4; j++) { + key[j] ^= key[j - 1]; + } + for (i = 0; i < 4; i++) { + k8[4][i] ^= xS[k8[3][i]]; + } + for (j = 5; j < 8; j++) { + key[j] ^= key[j - 1]; + } + } + /* copy values into round key array */ + for (j = 0; (j < KC) && (t < (ROUNDS + 1) * BC); j++, t++) { + rkk->rk[t] = key[j]; + } + } + + /* make roundkey structure */ + rkk->BC = BC; + rkk->KC = KC; + rkk->ROUNDS = ROUNDS; + for (i = 0; i < 2; i++) { + for (j = 0; j < 4; j++) { + rkk->shift[i][j] = xshifts[(BC - 4) >> 1][i][j]; + } + } + + return 0; +} + +/* Encryption of one block. */ + +void xrijndaelEncrypt(word32 block[], roundkey *rkk) +{ + word32 block2[MAXBC]; /* hold intermediate result */ + int r; + + int *shift = rkk->shift[0]; + int BC = rkk->BC; + int ROUNDS = rkk->ROUNDS; + word32 *rp = rkk->rk; + + /* begin with a key addition */ + xKeyAddition(block, block, rp, BC); + rp += BC; + + /* ROUNDS-1 ordinary rounds */ + for (r = 1; r < ROUNDS; r++) { + xShiftSubst(block2, block, shift, BC, xS); + xMixAdd(block, block2, rp, BC); + rp += BC; + } + + /* Last round is special: there is no xMixColumn */ + xShiftSubst(block2, block, shift, BC, xS); + xKeyAddition(block, block2, rp, BC); +} + +void xrijndaelDecrypt(word32 block[], roundkey *rkk) +{ + word32 block2[MAXBC]; /* hold intermediate result */ + int r; + + int *shift = rkk->shift[1]; + int BC = rkk->BC; + int ROUNDS = rkk->ROUNDS; + word32 *rp = rkk->rk + ROUNDS * BC; + + /* To decrypt: apply the inverse operations of the encrypt routine, + * in opposite order + * + * (xKeyAddition is an involution: it's equal to its inverse) + * (the inverse of xSubstitution with table S is xSubstitution with the + * inverse table of S) + * (the inverse of xShiftRow is xShiftRow over a suitable distance) + */ + + /* First the special round: + * without xInvMixColumn + * with extra xKeyAddition + */ + xKeyAddition(block2, block, rp, BC); + xShiftSubst(block, block2, shift, BC, xSi); + rp -= BC; + + /* ROUNDS-1 ordinary rounds + */ + for (r = ROUNDS - 1; r > 0; r--) { + xKeyAddition(block, block, rp, BC); + xInvMixColumn(block2, block, BC); + xShiftSubst(block, block2, shift, BC, xSi); + rp -= BC; + } + + /* End with the extra key addition + */ + + xKeyAddition(block, block, rp, BC); +} + +uint8_t ao_aes_mutex; +static roundkey rkk; + +static uint8_t iv[16]; + +void +ao_aes_set_mode(enum ao_aes_mode mode) +{ + /* we only do CBC_MAC anyways... */ +} + +void +ao_aes_set_key(__xdata uint8_t *in) +{ + xrijndaelKeySched((word32 *) in, 128, 128, &rkk); +} + +void +ao_aes_zero_iv(void) +{ + memset(iv, '\0', sizeof (iv)); +} + +void +ao_aes_run(__xdata uint8_t *in, + __xdata uint8_t *out) +{ + uint8_t i; + + for (i = 0; i < 16; i++) + iv[i] ^= in[i]; + xrijndaelEncrypt((word32 *) iv, &rkk); + if (out) + memcpy(out, iv, 16); +} + +void +ao_aes_init(void) +{ +} diff --git a/src/aes/ao_aes_int.h b/src/aes/ao_aes_int.h new file mode 100644 index 00000000..7990a2e1 --- /dev/null +++ b/src/aes/ao_aes_int.h @@ -0,0 +1,64 @@ +/* Copyright (C) 2000-2009 Peter Selinger. + This file is part of ccrypt. It is free software and it is covered + by the GNU general public license. See the file COPYING for details. */ + +/* rijndael.h */ +/* $Id: rijndael.h 258 2009-08-26 17:46:10Z selinger $ */ + +/* derived from original source: rijndael-alg-ref.h v2.0 August '99 + * Reference ANSI C code for NIST competition + * authors: Paulo Barreto + * Vincent Rijmen + */ + +#ifndef __RIJNDAEL_H +#define __RIJNDAEL_H + +#include + +typedef uint8_t word8; +typedef uint32_t word32; + +/* a type to hold 32 bits accessible as 1 integer or 4 bytes */ +union word8x4_u { + word8 w8[4]; + word32 w32; +}; +typedef union word8x4_u word8x4; + +#include "ao_aes_tables.h" + +#define MAXBC (256/32) +#define MAXKC (256/32) +#define MAXROUNDS 14 +#define MAXRK ((MAXROUNDS+1)*MAXBC) + +typedef struct { + int BC; + int KC; + int ROUNDS; + int shift[2][4]; + word32 rk[MAXRK]; +} roundkey; + +/* keys and blocks are externally treated as word32 arrays, to + make sure they are aligned on 4-byte boundaries on architectures + that require it. */ + +/* make a roundkey rkk from key. key must have appropriate size given + by keyBits. keyBits and blockBits may only be 128, 196, or + 256. Returns non-zero if arguments are invalid. */ + +int xrijndaelKeySched(word32 key[], int keyBits, int blockBits, + roundkey *rkk); + +/* encrypt, resp. decrypt, block using rijndael roundkey rkk. rkk must + have been created with xrijndaelKeySched. Size of block, in bits, + must be equal to blockBits parameter that was used to make rkk. In + all other cases, behavior is undefined - for reasons of speed, no + check for error conditions is done. */ + +void xrijndaelEncrypt(word32 block[], roundkey *rkk); +void xrijndaelDecrypt(word32 block[], roundkey *rkk); + +#endif /* __RIJNDAEL_H */ diff --git a/src/aes/ao_aes_tables.c b/src/aes/ao_aes_tables.c new file mode 100644 index 00000000..1bca227c --- /dev/null +++ b/src/aes/ao_aes_tables.c @@ -0,0 +1,768 @@ +/* Copyright (C) 2000-2009 Peter Selinger. + This file is part of ccrypt. It is free software and it is covered + by the GNU general public license. See the file COPYING for details. */ + +/* generated by maketables.c */ + +#include "ao_aes_int.h" + +const word8x4 M0[4][256] = { + { + {{ 0, 0, 0, 0}}, {{ 2, 1, 1, 3}}, {{ 4, 2, 2, 6}}, + {{ 6, 3, 3, 5}}, {{ 8, 4, 4, 12}}, {{ 10, 5, 5, 15}}, + {{ 12, 6, 6, 10}}, {{ 14, 7, 7, 9}}, {{ 16, 8, 8, 24}}, + {{ 18, 9, 9, 27}}, {{ 20, 10, 10, 30}}, {{ 22, 11, 11, 29}}, + {{ 24, 12, 12, 20}}, {{ 26, 13, 13, 23}}, {{ 28, 14, 14, 18}}, + {{ 30, 15, 15, 17}}, {{ 32, 16, 16, 48}}, {{ 34, 17, 17, 51}}, + {{ 36, 18, 18, 54}}, {{ 38, 19, 19, 53}}, {{ 40, 20, 20, 60}}, + {{ 42, 21, 21, 63}}, {{ 44, 22, 22, 58}}, {{ 46, 23, 23, 57}}, + {{ 48, 24, 24, 40}}, {{ 50, 25, 25, 43}}, {{ 52, 26, 26, 46}}, + {{ 54, 27, 27, 45}}, {{ 56, 28, 28, 36}}, {{ 58, 29, 29, 39}}, + {{ 60, 30, 30, 34}}, {{ 62, 31, 31, 33}}, {{ 64, 32, 32, 96}}, + {{ 66, 33, 33, 99}}, {{ 68, 34, 34, 102}}, {{ 70, 35, 35, 101}}, + {{ 72, 36, 36, 108}}, {{ 74, 37, 37, 111}}, {{ 76, 38, 38, 106}}, + {{ 78, 39, 39, 105}}, {{ 80, 40, 40, 120}}, {{ 82, 41, 41, 123}}, + {{ 84, 42, 42, 126}}, {{ 86, 43, 43, 125}}, {{ 88, 44, 44, 116}}, + {{ 90, 45, 45, 119}}, {{ 92, 46, 46, 114}}, {{ 94, 47, 47, 113}}, + {{ 96, 48, 48, 80}}, {{ 98, 49, 49, 83}}, {{100, 50, 50, 86}}, + {{102, 51, 51, 85}}, {{104, 52, 52, 92}}, {{106, 53, 53, 95}}, + {{108, 54, 54, 90}}, {{110, 55, 55, 89}}, {{112, 56, 56, 72}}, + {{114, 57, 57, 75}}, {{116, 58, 58, 78}}, {{118, 59, 59, 77}}, + {{120, 60, 60, 68}}, {{122, 61, 61, 71}}, {{124, 62, 62, 66}}, + {{126, 63, 63, 65}}, {{128, 64, 64, 192}}, {{130, 65, 65, 195}}, + {{132, 66, 66, 198}}, {{134, 67, 67, 197}}, {{136, 68, 68, 204}}, + {{138, 69, 69, 207}}, {{140, 70, 70, 202}}, {{142, 71, 71, 201}}, + {{144, 72, 72, 216}}, {{146, 73, 73, 219}}, {{148, 74, 74, 222}}, + {{150, 75, 75, 221}}, {{152, 76, 76, 212}}, {{154, 77, 77, 215}}, + {{156, 78, 78, 210}}, {{158, 79, 79, 209}}, {{160, 80, 80, 240}}, + {{162, 81, 81, 243}}, {{164, 82, 82, 246}}, {{166, 83, 83, 245}}, + {{168, 84, 84, 252}}, {{170, 85, 85, 255}}, {{172, 86, 86, 250}}, + {{174, 87, 87, 249}}, {{176, 88, 88, 232}}, {{178, 89, 89, 235}}, + {{180, 90, 90, 238}}, {{182, 91, 91, 237}}, {{184, 92, 92, 228}}, + {{186, 93, 93, 231}}, {{188, 94, 94, 226}}, {{190, 95, 95, 225}}, + {{192, 96, 96, 160}}, {{194, 97, 97, 163}}, {{196, 98, 98, 166}}, + {{198, 99, 99, 165}}, {{200, 100, 100, 172}}, {{202, 101, 101, 175}}, + {{204, 102, 102, 170}}, {{206, 103, 103, 169}}, {{208, 104, 104, 184}}, + {{210, 105, 105, 187}}, {{212, 106, 106, 190}}, {{214, 107, 107, 189}}, + {{216, 108, 108, 180}}, {{218, 109, 109, 183}}, {{220, 110, 110, 178}}, + {{222, 111, 111, 177}}, {{224, 112, 112, 144}}, {{226, 113, 113, 147}}, + {{228, 114, 114, 150}}, {{230, 115, 115, 149}}, {{232, 116, 116, 156}}, + {{234, 117, 117, 159}}, {{236, 118, 118, 154}}, {{238, 119, 119, 153}}, + {{240, 120, 120, 136}}, {{242, 121, 121, 139}}, {{244, 122, 122, 142}}, + {{246, 123, 123, 141}}, {{248, 124, 124, 132}}, {{250, 125, 125, 135}}, + {{252, 126, 126, 130}}, {{254, 127, 127, 129}}, {{ 27, 128, 128, 155}}, + {{ 25, 129, 129, 152}}, {{ 31, 130, 130, 157}}, {{ 29, 131, 131, 158}}, + {{ 19, 132, 132, 151}}, {{ 17, 133, 133, 148}}, {{ 23, 134, 134, 145}}, + {{ 21, 135, 135, 146}}, {{ 11, 136, 136, 131}}, {{ 9, 137, 137, 128}}, + {{ 15, 138, 138, 133}}, {{ 13, 139, 139, 134}}, {{ 3, 140, 140, 143}}, + {{ 1, 141, 141, 140}}, {{ 7, 142, 142, 137}}, {{ 5, 143, 143, 138}}, + {{ 59, 144, 144, 171}}, {{ 57, 145, 145, 168}}, {{ 63, 146, 146, 173}}, + {{ 61, 147, 147, 174}}, {{ 51, 148, 148, 167}}, {{ 49, 149, 149, 164}}, + {{ 55, 150, 150, 161}}, {{ 53, 151, 151, 162}}, {{ 43, 152, 152, 179}}, + {{ 41, 153, 153, 176}}, {{ 47, 154, 154, 181}}, {{ 45, 155, 155, 182}}, + {{ 35, 156, 156, 191}}, {{ 33, 157, 157, 188}}, {{ 39, 158, 158, 185}}, + {{ 37, 159, 159, 186}}, {{ 91, 160, 160, 251}}, {{ 89, 161, 161, 248}}, + {{ 95, 162, 162, 253}}, {{ 93, 163, 163, 254}}, {{ 83, 164, 164, 247}}, + {{ 81, 165, 165, 244}}, {{ 87, 166, 166, 241}}, {{ 85, 167, 167, 242}}, + {{ 75, 168, 168, 227}}, {{ 73, 169, 169, 224}}, {{ 79, 170, 170, 229}}, + {{ 77, 171, 171, 230}}, {{ 67, 172, 172, 239}}, {{ 65, 173, 173, 236}}, + {{ 71, 174, 174, 233}}, {{ 69, 175, 175, 234}}, {{123, 176, 176, 203}}, + {{121, 177, 177, 200}}, {{127, 178, 178, 205}}, {{125, 179, 179, 206}}, + {{115, 180, 180, 199}}, {{113, 181, 181, 196}}, {{119, 182, 182, 193}}, + {{117, 183, 183, 194}}, {{107, 184, 184, 211}}, {{105, 185, 185, 208}}, + {{111, 186, 186, 213}}, {{109, 187, 187, 214}}, {{ 99, 188, 188, 223}}, + {{ 97, 189, 189, 220}}, {{103, 190, 190, 217}}, {{101, 191, 191, 218}}, + {{155, 192, 192, 91}}, {{153, 193, 193, 88}}, {{159, 194, 194, 93}}, + {{157, 195, 195, 94}}, {{147, 196, 196, 87}}, {{145, 197, 197, 84}}, + {{151, 198, 198, 81}}, {{149, 199, 199, 82}}, {{139, 200, 200, 67}}, + {{137, 201, 201, 64}}, {{143, 202, 202, 69}}, {{141, 203, 203, 70}}, + {{131, 204, 204, 79}}, {{129, 205, 205, 76}}, {{135, 206, 206, 73}}, + {{133, 207, 207, 74}}, {{187, 208, 208, 107}}, {{185, 209, 209, 104}}, + {{191, 210, 210, 109}}, {{189, 211, 211, 110}}, {{179, 212, 212, 103}}, + {{177, 213, 213, 100}}, {{183, 214, 214, 97}}, {{181, 215, 215, 98}}, + {{171, 216, 216, 115}}, {{169, 217, 217, 112}}, {{175, 218, 218, 117}}, + {{173, 219, 219, 118}}, {{163, 220, 220, 127}}, {{161, 221, 221, 124}}, + {{167, 222, 222, 121}}, {{165, 223, 223, 122}}, {{219, 224, 224, 59}}, + {{217, 225, 225, 56}}, {{223, 226, 226, 61}}, {{221, 227, 227, 62}}, + {{211, 228, 228, 55}}, {{209, 229, 229, 52}}, {{215, 230, 230, 49}}, + {{213, 231, 231, 50}}, {{203, 232, 232, 35}}, {{201, 233, 233, 32}}, + {{207, 234, 234, 37}}, {{205, 235, 235, 38}}, {{195, 236, 236, 47}}, + {{193, 237, 237, 44}}, {{199, 238, 238, 41}}, {{197, 239, 239, 42}}, + {{251, 240, 240, 11}}, {{249, 241, 241, 8}}, {{255, 242, 242, 13}}, + {{253, 243, 243, 14}}, {{243, 244, 244, 7}}, {{241, 245, 245, 4}}, + {{247, 246, 246, 1}}, {{245, 247, 247, 2}}, {{235, 248, 248, 19}}, + {{233, 249, 249, 16}}, {{239, 250, 250, 21}}, {{237, 251, 251, 22}}, + {{227, 252, 252, 31}}, {{225, 253, 253, 28}}, {{231, 254, 254, 25}}, + {{229, 255, 255, 26}}, + }, + { + {{ 0, 0, 0, 0}}, {{ 3, 2, 1, 1}}, {{ 6, 4, 2, 2}}, + {{ 5, 6, 3, 3}}, {{ 12, 8, 4, 4}}, {{ 15, 10, 5, 5}}, + {{ 10, 12, 6, 6}}, {{ 9, 14, 7, 7}}, {{ 24, 16, 8, 8}}, + {{ 27, 18, 9, 9}}, {{ 30, 20, 10, 10}}, {{ 29, 22, 11, 11}}, + {{ 20, 24, 12, 12}}, {{ 23, 26, 13, 13}}, {{ 18, 28, 14, 14}}, + {{ 17, 30, 15, 15}}, {{ 48, 32, 16, 16}}, {{ 51, 34, 17, 17}}, + {{ 54, 36, 18, 18}}, {{ 53, 38, 19, 19}}, {{ 60, 40, 20, 20}}, + {{ 63, 42, 21, 21}}, {{ 58, 44, 22, 22}}, {{ 57, 46, 23, 23}}, + {{ 40, 48, 24, 24}}, {{ 43, 50, 25, 25}}, {{ 46, 52, 26, 26}}, + {{ 45, 54, 27, 27}}, {{ 36, 56, 28, 28}}, {{ 39, 58, 29, 29}}, + {{ 34, 60, 30, 30}}, {{ 33, 62, 31, 31}}, {{ 96, 64, 32, 32}}, + {{ 99, 66, 33, 33}}, {{102, 68, 34, 34}}, {{101, 70, 35, 35}}, + {{108, 72, 36, 36}}, {{111, 74, 37, 37}}, {{106, 76, 38, 38}}, + {{105, 78, 39, 39}}, {{120, 80, 40, 40}}, {{123, 82, 41, 41}}, + {{126, 84, 42, 42}}, {{125, 86, 43, 43}}, {{116, 88, 44, 44}}, + {{119, 90, 45, 45}}, {{114, 92, 46, 46}}, {{113, 94, 47, 47}}, + {{ 80, 96, 48, 48}}, {{ 83, 98, 49, 49}}, {{ 86, 100, 50, 50}}, + {{ 85, 102, 51, 51}}, {{ 92, 104, 52, 52}}, {{ 95, 106, 53, 53}}, + {{ 90, 108, 54, 54}}, {{ 89, 110, 55, 55}}, {{ 72, 112, 56, 56}}, + {{ 75, 114, 57, 57}}, {{ 78, 116, 58, 58}}, {{ 77, 118, 59, 59}}, + {{ 68, 120, 60, 60}}, {{ 71, 122, 61, 61}}, {{ 66, 124, 62, 62}}, + {{ 65, 126, 63, 63}}, {{192, 128, 64, 64}}, {{195, 130, 65, 65}}, + {{198, 132, 66, 66}}, {{197, 134, 67, 67}}, {{204, 136, 68, 68}}, + {{207, 138, 69, 69}}, {{202, 140, 70, 70}}, {{201, 142, 71, 71}}, + {{216, 144, 72, 72}}, {{219, 146, 73, 73}}, {{222, 148, 74, 74}}, + {{221, 150, 75, 75}}, {{212, 152, 76, 76}}, {{215, 154, 77, 77}}, + {{210, 156, 78, 78}}, {{209, 158, 79, 79}}, {{240, 160, 80, 80}}, + {{243, 162, 81, 81}}, {{246, 164, 82, 82}}, {{245, 166, 83, 83}}, + {{252, 168, 84, 84}}, {{255, 170, 85, 85}}, {{250, 172, 86, 86}}, + {{249, 174, 87, 87}}, {{232, 176, 88, 88}}, {{235, 178, 89, 89}}, + {{238, 180, 90, 90}}, {{237, 182, 91, 91}}, {{228, 184, 92, 92}}, + {{231, 186, 93, 93}}, {{226, 188, 94, 94}}, {{225, 190, 95, 95}}, + {{160, 192, 96, 96}}, {{163, 194, 97, 97}}, {{166, 196, 98, 98}}, + {{165, 198, 99, 99}}, {{172, 200, 100, 100}}, {{175, 202, 101, 101}}, + {{170, 204, 102, 102}}, {{169, 206, 103, 103}}, {{184, 208, 104, 104}}, + {{187, 210, 105, 105}}, {{190, 212, 106, 106}}, {{189, 214, 107, 107}}, + {{180, 216, 108, 108}}, {{183, 218, 109, 109}}, {{178, 220, 110, 110}}, + {{177, 222, 111, 111}}, {{144, 224, 112, 112}}, {{147, 226, 113, 113}}, + {{150, 228, 114, 114}}, {{149, 230, 115, 115}}, {{156, 232, 116, 116}}, + {{159, 234, 117, 117}}, {{154, 236, 118, 118}}, {{153, 238, 119, 119}}, + {{136, 240, 120, 120}}, {{139, 242, 121, 121}}, {{142, 244, 122, 122}}, + {{141, 246, 123, 123}}, {{132, 248, 124, 124}}, {{135, 250, 125, 125}}, + {{130, 252, 126, 126}}, {{129, 254, 127, 127}}, {{155, 27, 128, 128}}, + {{152, 25, 129, 129}}, {{157, 31, 130, 130}}, {{158, 29, 131, 131}}, + {{151, 19, 132, 132}}, {{148, 17, 133, 133}}, {{145, 23, 134, 134}}, + {{146, 21, 135, 135}}, {{131, 11, 136, 136}}, {{128, 9, 137, 137}}, + {{133, 15, 138, 138}}, {{134, 13, 139, 139}}, {{143, 3, 140, 140}}, + {{140, 1, 141, 141}}, {{137, 7, 142, 142}}, {{138, 5, 143, 143}}, + {{171, 59, 144, 144}}, {{168, 57, 145, 145}}, {{173, 63, 146, 146}}, + {{174, 61, 147, 147}}, {{167, 51, 148, 148}}, {{164, 49, 149, 149}}, + {{161, 55, 150, 150}}, {{162, 53, 151, 151}}, {{179, 43, 152, 152}}, + {{176, 41, 153, 153}}, {{181, 47, 154, 154}}, {{182, 45, 155, 155}}, + {{191, 35, 156, 156}}, {{188, 33, 157, 157}}, {{185, 39, 158, 158}}, + {{186, 37, 159, 159}}, {{251, 91, 160, 160}}, {{248, 89, 161, 161}}, + {{253, 95, 162, 162}}, {{254, 93, 163, 163}}, {{247, 83, 164, 164}}, + {{244, 81, 165, 165}}, {{241, 87, 166, 166}}, {{242, 85, 167, 167}}, + {{227, 75, 168, 168}}, {{224, 73, 169, 169}}, {{229, 79, 170, 170}}, + {{230, 77, 171, 171}}, {{239, 67, 172, 172}}, {{236, 65, 173, 173}}, + {{233, 71, 174, 174}}, {{234, 69, 175, 175}}, {{203, 123, 176, 176}}, + {{200, 121, 177, 177}}, {{205, 127, 178, 178}}, {{206, 125, 179, 179}}, + {{199, 115, 180, 180}}, {{196, 113, 181, 181}}, {{193, 119, 182, 182}}, + {{194, 117, 183, 183}}, {{211, 107, 184, 184}}, {{208, 105, 185, 185}}, + {{213, 111, 186, 186}}, {{214, 109, 187, 187}}, {{223, 99, 188, 188}}, + {{220, 97, 189, 189}}, {{217, 103, 190, 190}}, {{218, 101, 191, 191}}, + {{ 91, 155, 192, 192}}, {{ 88, 153, 193, 193}}, {{ 93, 159, 194, 194}}, + {{ 94, 157, 195, 195}}, {{ 87, 147, 196, 196}}, {{ 84, 145, 197, 197}}, + {{ 81, 151, 198, 198}}, {{ 82, 149, 199, 199}}, {{ 67, 139, 200, 200}}, + {{ 64, 137, 201, 201}}, {{ 69, 143, 202, 202}}, {{ 70, 141, 203, 203}}, + {{ 79, 131, 204, 204}}, {{ 76, 129, 205, 205}}, {{ 73, 135, 206, 206}}, + {{ 74, 133, 207, 207}}, {{107, 187, 208, 208}}, {{104, 185, 209, 209}}, + {{109, 191, 210, 210}}, {{110, 189, 211, 211}}, {{103, 179, 212, 212}}, + {{100, 177, 213, 213}}, {{ 97, 183, 214, 214}}, {{ 98, 181, 215, 215}}, + {{115, 171, 216, 216}}, {{112, 169, 217, 217}}, {{117, 175, 218, 218}}, + {{118, 173, 219, 219}}, {{127, 163, 220, 220}}, {{124, 161, 221, 221}}, + {{121, 167, 222, 222}}, {{122, 165, 223, 223}}, {{ 59, 219, 224, 224}}, + {{ 56, 217, 225, 225}}, {{ 61, 223, 226, 226}}, {{ 62, 221, 227, 227}}, + {{ 55, 211, 228, 228}}, {{ 52, 209, 229, 229}}, {{ 49, 215, 230, 230}}, + {{ 50, 213, 231, 231}}, {{ 35, 203, 232, 232}}, {{ 32, 201, 233, 233}}, + {{ 37, 207, 234, 234}}, {{ 38, 205, 235, 235}}, {{ 47, 195, 236, 236}}, + {{ 44, 193, 237, 237}}, {{ 41, 199, 238, 238}}, {{ 42, 197, 239, 239}}, + {{ 11, 251, 240, 240}}, {{ 8, 249, 241, 241}}, {{ 13, 255, 242, 242}}, + {{ 14, 253, 243, 243}}, {{ 7, 243, 244, 244}}, {{ 4, 241, 245, 245}}, + {{ 1, 247, 246, 246}}, {{ 2, 245, 247, 247}}, {{ 19, 235, 248, 248}}, + {{ 16, 233, 249, 249}}, {{ 21, 239, 250, 250}}, {{ 22, 237, 251, 251}}, + {{ 31, 227, 252, 252}}, {{ 28, 225, 253, 253}}, {{ 25, 231, 254, 254}}, + {{ 26, 229, 255, 255}}, + }, + { + {{ 0, 0, 0, 0}}, {{ 1, 3, 2, 1}}, {{ 2, 6, 4, 2}}, + {{ 3, 5, 6, 3}}, {{ 4, 12, 8, 4}}, {{ 5, 15, 10, 5}}, + {{ 6, 10, 12, 6}}, {{ 7, 9, 14, 7}}, {{ 8, 24, 16, 8}}, + {{ 9, 27, 18, 9}}, {{ 10, 30, 20, 10}}, {{ 11, 29, 22, 11}}, + {{ 12, 20, 24, 12}}, {{ 13, 23, 26, 13}}, {{ 14, 18, 28, 14}}, + {{ 15, 17, 30, 15}}, {{ 16, 48, 32, 16}}, {{ 17, 51, 34, 17}}, + {{ 18, 54, 36, 18}}, {{ 19, 53, 38, 19}}, {{ 20, 60, 40, 20}}, + {{ 21, 63, 42, 21}}, {{ 22, 58, 44, 22}}, {{ 23, 57, 46, 23}}, + {{ 24, 40, 48, 24}}, {{ 25, 43, 50, 25}}, {{ 26, 46, 52, 26}}, + {{ 27, 45, 54, 27}}, {{ 28, 36, 56, 28}}, {{ 29, 39, 58, 29}}, + {{ 30, 34, 60, 30}}, {{ 31, 33, 62, 31}}, {{ 32, 96, 64, 32}}, + {{ 33, 99, 66, 33}}, {{ 34, 102, 68, 34}}, {{ 35, 101, 70, 35}}, + {{ 36, 108, 72, 36}}, {{ 37, 111, 74, 37}}, {{ 38, 106, 76, 38}}, + {{ 39, 105, 78, 39}}, {{ 40, 120, 80, 40}}, {{ 41, 123, 82, 41}}, + {{ 42, 126, 84, 42}}, {{ 43, 125, 86, 43}}, {{ 44, 116, 88, 44}}, + {{ 45, 119, 90, 45}}, {{ 46, 114, 92, 46}}, {{ 47, 113, 94, 47}}, + {{ 48, 80, 96, 48}}, {{ 49, 83, 98, 49}}, {{ 50, 86, 100, 50}}, + {{ 51, 85, 102, 51}}, {{ 52, 92, 104, 52}}, {{ 53, 95, 106, 53}}, + {{ 54, 90, 108, 54}}, {{ 55, 89, 110, 55}}, {{ 56, 72, 112, 56}}, + {{ 57, 75, 114, 57}}, {{ 58, 78, 116, 58}}, {{ 59, 77, 118, 59}}, + {{ 60, 68, 120, 60}}, {{ 61, 71, 122, 61}}, {{ 62, 66, 124, 62}}, + {{ 63, 65, 126, 63}}, {{ 64, 192, 128, 64}}, {{ 65, 195, 130, 65}}, + {{ 66, 198, 132, 66}}, {{ 67, 197, 134, 67}}, {{ 68, 204, 136, 68}}, + {{ 69, 207, 138, 69}}, {{ 70, 202, 140, 70}}, {{ 71, 201, 142, 71}}, + {{ 72, 216, 144, 72}}, {{ 73, 219, 146, 73}}, {{ 74, 222, 148, 74}}, + {{ 75, 221, 150, 75}}, {{ 76, 212, 152, 76}}, {{ 77, 215, 154, 77}}, + {{ 78, 210, 156, 78}}, {{ 79, 209, 158, 79}}, {{ 80, 240, 160, 80}}, + {{ 81, 243, 162, 81}}, {{ 82, 246, 164, 82}}, {{ 83, 245, 166, 83}}, + {{ 84, 252, 168, 84}}, {{ 85, 255, 170, 85}}, {{ 86, 250, 172, 86}}, + {{ 87, 249, 174, 87}}, {{ 88, 232, 176, 88}}, {{ 89, 235, 178, 89}}, + {{ 90, 238, 180, 90}}, {{ 91, 237, 182, 91}}, {{ 92, 228, 184, 92}}, + {{ 93, 231, 186, 93}}, {{ 94, 226, 188, 94}}, {{ 95, 225, 190, 95}}, + {{ 96, 160, 192, 96}}, {{ 97, 163, 194, 97}}, {{ 98, 166, 196, 98}}, + {{ 99, 165, 198, 99}}, {{100, 172, 200, 100}}, {{101, 175, 202, 101}}, + {{102, 170, 204, 102}}, {{103, 169, 206, 103}}, {{104, 184, 208, 104}}, + {{105, 187, 210, 105}}, {{106, 190, 212, 106}}, {{107, 189, 214, 107}}, + {{108, 180, 216, 108}}, {{109, 183, 218, 109}}, {{110, 178, 220, 110}}, + {{111, 177, 222, 111}}, {{112, 144, 224, 112}}, {{113, 147, 226, 113}}, + {{114, 150, 228, 114}}, {{115, 149, 230, 115}}, {{116, 156, 232, 116}}, + {{117, 159, 234, 117}}, {{118, 154, 236, 118}}, {{119, 153, 238, 119}}, + {{120, 136, 240, 120}}, {{121, 139, 242, 121}}, {{122, 142, 244, 122}}, + {{123, 141, 246, 123}}, {{124, 132, 248, 124}}, {{125, 135, 250, 125}}, + {{126, 130, 252, 126}}, {{127, 129, 254, 127}}, {{128, 155, 27, 128}}, + {{129, 152, 25, 129}}, {{130, 157, 31, 130}}, {{131, 158, 29, 131}}, + {{132, 151, 19, 132}}, {{133, 148, 17, 133}}, {{134, 145, 23, 134}}, + {{135, 146, 21, 135}}, {{136, 131, 11, 136}}, {{137, 128, 9, 137}}, + {{138, 133, 15, 138}}, {{139, 134, 13, 139}}, {{140, 143, 3, 140}}, + {{141, 140, 1, 141}}, {{142, 137, 7, 142}}, {{143, 138, 5, 143}}, + {{144, 171, 59, 144}}, {{145, 168, 57, 145}}, {{146, 173, 63, 146}}, + {{147, 174, 61, 147}}, {{148, 167, 51, 148}}, {{149, 164, 49, 149}}, + {{150, 161, 55, 150}}, {{151, 162, 53, 151}}, {{152, 179, 43, 152}}, + {{153, 176, 41, 153}}, {{154, 181, 47, 154}}, {{155, 182, 45, 155}}, + {{156, 191, 35, 156}}, {{157, 188, 33, 157}}, {{158, 185, 39, 158}}, + {{159, 186, 37, 159}}, {{160, 251, 91, 160}}, {{161, 248, 89, 161}}, + {{162, 253, 95, 162}}, {{163, 254, 93, 163}}, {{164, 247, 83, 164}}, + {{165, 244, 81, 165}}, {{166, 241, 87, 166}}, {{167, 242, 85, 167}}, + {{168, 227, 75, 168}}, {{169, 224, 73, 169}}, {{170, 229, 79, 170}}, + {{171, 230, 77, 171}}, {{172, 239, 67, 172}}, {{173, 236, 65, 173}}, + {{174, 233, 71, 174}}, {{175, 234, 69, 175}}, {{176, 203, 123, 176}}, + {{177, 200, 121, 177}}, {{178, 205, 127, 178}}, {{179, 206, 125, 179}}, + {{180, 199, 115, 180}}, {{181, 196, 113, 181}}, {{182, 193, 119, 182}}, + {{183, 194, 117, 183}}, {{184, 211, 107, 184}}, {{185, 208, 105, 185}}, + {{186, 213, 111, 186}}, {{187, 214, 109, 187}}, {{188, 223, 99, 188}}, + {{189, 220, 97, 189}}, {{190, 217, 103, 190}}, {{191, 218, 101, 191}}, + {{192, 91, 155, 192}}, {{193, 88, 153, 193}}, {{194, 93, 159, 194}}, + {{195, 94, 157, 195}}, {{196, 87, 147, 196}}, {{197, 84, 145, 197}}, + {{198, 81, 151, 198}}, {{199, 82, 149, 199}}, {{200, 67, 139, 200}}, + {{201, 64, 137, 201}}, {{202, 69, 143, 202}}, {{203, 70, 141, 203}}, + {{204, 79, 131, 204}}, {{205, 76, 129, 205}}, {{206, 73, 135, 206}}, + {{207, 74, 133, 207}}, {{208, 107, 187, 208}}, {{209, 104, 185, 209}}, + {{210, 109, 191, 210}}, {{211, 110, 189, 211}}, {{212, 103, 179, 212}}, + {{213, 100, 177, 213}}, {{214, 97, 183, 214}}, {{215, 98, 181, 215}}, + {{216, 115, 171, 216}}, {{217, 112, 169, 217}}, {{218, 117, 175, 218}}, + {{219, 118, 173, 219}}, {{220, 127, 163, 220}}, {{221, 124, 161, 221}}, + {{222, 121, 167, 222}}, {{223, 122, 165, 223}}, {{224, 59, 219, 224}}, + {{225, 56, 217, 225}}, {{226, 61, 223, 226}}, {{227, 62, 221, 227}}, + {{228, 55, 211, 228}}, {{229, 52, 209, 229}}, {{230, 49, 215, 230}}, + {{231, 50, 213, 231}}, {{232, 35, 203, 232}}, {{233, 32, 201, 233}}, + {{234, 37, 207, 234}}, {{235, 38, 205, 235}}, {{236, 47, 195, 236}}, + {{237, 44, 193, 237}}, {{238, 41, 199, 238}}, {{239, 42, 197, 239}}, + {{240, 11, 251, 240}}, {{241, 8, 249, 241}}, {{242, 13, 255, 242}}, + {{243, 14, 253, 243}}, {{244, 7, 243, 244}}, {{245, 4, 241, 245}}, + {{246, 1, 247, 246}}, {{247, 2, 245, 247}}, {{248, 19, 235, 248}}, + {{249, 16, 233, 249}}, {{250, 21, 239, 250}}, {{251, 22, 237, 251}}, + {{252, 31, 227, 252}}, {{253, 28, 225, 253}}, {{254, 25, 231, 254}}, + {{255, 26, 229, 255}}, + }, + { + {{ 0, 0, 0, 0}}, {{ 1, 1, 3, 2}}, {{ 2, 2, 6, 4}}, + {{ 3, 3, 5, 6}}, {{ 4, 4, 12, 8}}, {{ 5, 5, 15, 10}}, + {{ 6, 6, 10, 12}}, {{ 7, 7, 9, 14}}, {{ 8, 8, 24, 16}}, + {{ 9, 9, 27, 18}}, {{ 10, 10, 30, 20}}, {{ 11, 11, 29, 22}}, + {{ 12, 12, 20, 24}}, {{ 13, 13, 23, 26}}, {{ 14, 14, 18, 28}}, + {{ 15, 15, 17, 30}}, {{ 16, 16, 48, 32}}, {{ 17, 17, 51, 34}}, + {{ 18, 18, 54, 36}}, {{ 19, 19, 53, 38}}, {{ 20, 20, 60, 40}}, + {{ 21, 21, 63, 42}}, {{ 22, 22, 58, 44}}, {{ 23, 23, 57, 46}}, + {{ 24, 24, 40, 48}}, {{ 25, 25, 43, 50}}, {{ 26, 26, 46, 52}}, + {{ 27, 27, 45, 54}}, {{ 28, 28, 36, 56}}, {{ 29, 29, 39, 58}}, + {{ 30, 30, 34, 60}}, {{ 31, 31, 33, 62}}, {{ 32, 32, 96, 64}}, + {{ 33, 33, 99, 66}}, {{ 34, 34, 102, 68}}, {{ 35, 35, 101, 70}}, + {{ 36, 36, 108, 72}}, {{ 37, 37, 111, 74}}, {{ 38, 38, 106, 76}}, + {{ 39, 39, 105, 78}}, {{ 40, 40, 120, 80}}, {{ 41, 41, 123, 82}}, + {{ 42, 42, 126, 84}}, {{ 43, 43, 125, 86}}, {{ 44, 44, 116, 88}}, + {{ 45, 45, 119, 90}}, {{ 46, 46, 114, 92}}, {{ 47, 47, 113, 94}}, + {{ 48, 48, 80, 96}}, {{ 49, 49, 83, 98}}, {{ 50, 50, 86, 100}}, + {{ 51, 51, 85, 102}}, {{ 52, 52, 92, 104}}, {{ 53, 53, 95, 106}}, + {{ 54, 54, 90, 108}}, {{ 55, 55, 89, 110}}, {{ 56, 56, 72, 112}}, + {{ 57, 57, 75, 114}}, {{ 58, 58, 78, 116}}, {{ 59, 59, 77, 118}}, + {{ 60, 60, 68, 120}}, {{ 61, 61, 71, 122}}, {{ 62, 62, 66, 124}}, + {{ 63, 63, 65, 126}}, {{ 64, 64, 192, 128}}, {{ 65, 65, 195, 130}}, + {{ 66, 66, 198, 132}}, {{ 67, 67, 197, 134}}, {{ 68, 68, 204, 136}}, + {{ 69, 69, 207, 138}}, {{ 70, 70, 202, 140}}, {{ 71, 71, 201, 142}}, + {{ 72, 72, 216, 144}}, {{ 73, 73, 219, 146}}, {{ 74, 74, 222, 148}}, + {{ 75, 75, 221, 150}}, {{ 76, 76, 212, 152}}, {{ 77, 77, 215, 154}}, + {{ 78, 78, 210, 156}}, {{ 79, 79, 209, 158}}, {{ 80, 80, 240, 160}}, + {{ 81, 81, 243, 162}}, {{ 82, 82, 246, 164}}, {{ 83, 83, 245, 166}}, + {{ 84, 84, 252, 168}}, {{ 85, 85, 255, 170}}, {{ 86, 86, 250, 172}}, + {{ 87, 87, 249, 174}}, {{ 88, 88, 232, 176}}, {{ 89, 89, 235, 178}}, + {{ 90, 90, 238, 180}}, {{ 91, 91, 237, 182}}, {{ 92, 92, 228, 184}}, + {{ 93, 93, 231, 186}}, {{ 94, 94, 226, 188}}, {{ 95, 95, 225, 190}}, + {{ 96, 96, 160, 192}}, {{ 97, 97, 163, 194}}, {{ 98, 98, 166, 196}}, + {{ 99, 99, 165, 198}}, {{100, 100, 172, 200}}, {{101, 101, 175, 202}}, + {{102, 102, 170, 204}}, {{103, 103, 169, 206}}, {{104, 104, 184, 208}}, + {{105, 105, 187, 210}}, {{106, 106, 190, 212}}, {{107, 107, 189, 214}}, + {{108, 108, 180, 216}}, {{109, 109, 183, 218}}, {{110, 110, 178, 220}}, + {{111, 111, 177, 222}}, {{112, 112, 144, 224}}, {{113, 113, 147, 226}}, + {{114, 114, 150, 228}}, {{115, 115, 149, 230}}, {{116, 116, 156, 232}}, + {{117, 117, 159, 234}}, {{118, 118, 154, 236}}, {{119, 119, 153, 238}}, + {{120, 120, 136, 240}}, {{121, 121, 139, 242}}, {{122, 122, 142, 244}}, + {{123, 123, 141, 246}}, {{124, 124, 132, 248}}, {{125, 125, 135, 250}}, + {{126, 126, 130, 252}}, {{127, 127, 129, 254}}, {{128, 128, 155, 27}}, + {{129, 129, 152, 25}}, {{130, 130, 157, 31}}, {{131, 131, 158, 29}}, + {{132, 132, 151, 19}}, {{133, 133, 148, 17}}, {{134, 134, 145, 23}}, + {{135, 135, 146, 21}}, {{136, 136, 131, 11}}, {{137, 137, 128, 9}}, + {{138, 138, 133, 15}}, {{139, 139, 134, 13}}, {{140, 140, 143, 3}}, + {{141, 141, 140, 1}}, {{142, 142, 137, 7}}, {{143, 143, 138, 5}}, + {{144, 144, 171, 59}}, {{145, 145, 168, 57}}, {{146, 146, 173, 63}}, + {{147, 147, 174, 61}}, {{148, 148, 167, 51}}, {{149, 149, 164, 49}}, + {{150, 150, 161, 55}}, {{151, 151, 162, 53}}, {{152, 152, 179, 43}}, + {{153, 153, 176, 41}}, {{154, 154, 181, 47}}, {{155, 155, 182, 45}}, + {{156, 156, 191, 35}}, {{157, 157, 188, 33}}, {{158, 158, 185, 39}}, + {{159, 159, 186, 37}}, {{160, 160, 251, 91}}, {{161, 161, 248, 89}}, + {{162, 162, 253, 95}}, {{163, 163, 254, 93}}, {{164, 164, 247, 83}}, + {{165, 165, 244, 81}}, {{166, 166, 241, 87}}, {{167, 167, 242, 85}}, + {{168, 168, 227, 75}}, {{169, 169, 224, 73}}, {{170, 170, 229, 79}}, + {{171, 171, 230, 77}}, {{172, 172, 239, 67}}, {{173, 173, 236, 65}}, + {{174, 174, 233, 71}}, {{175, 175, 234, 69}}, {{176, 176, 203, 123}}, + {{177, 177, 200, 121}}, {{178, 178, 205, 127}}, {{179, 179, 206, 125}}, + {{180, 180, 199, 115}}, {{181, 181, 196, 113}}, {{182, 182, 193, 119}}, + {{183, 183, 194, 117}}, {{184, 184, 211, 107}}, {{185, 185, 208, 105}}, + {{186, 186, 213, 111}}, {{187, 187, 214, 109}}, {{188, 188, 223, 99}}, + {{189, 189, 220, 97}}, {{190, 190, 217, 103}}, {{191, 191, 218, 101}}, + {{192, 192, 91, 155}}, {{193, 193, 88, 153}}, {{194, 194, 93, 159}}, + {{195, 195, 94, 157}}, {{196, 196, 87, 147}}, {{197, 197, 84, 145}}, + {{198, 198, 81, 151}}, {{199, 199, 82, 149}}, {{200, 200, 67, 139}}, + {{201, 201, 64, 137}}, {{202, 202, 69, 143}}, {{203, 203, 70, 141}}, + {{204, 204, 79, 131}}, {{205, 205, 76, 129}}, {{206, 206, 73, 135}}, + {{207, 207, 74, 133}}, {{208, 208, 107, 187}}, {{209, 209, 104, 185}}, + {{210, 210, 109, 191}}, {{211, 211, 110, 189}}, {{212, 212, 103, 179}}, + {{213, 213, 100, 177}}, {{214, 214, 97, 183}}, {{215, 215, 98, 181}}, + {{216, 216, 115, 171}}, {{217, 217, 112, 169}}, {{218, 218, 117, 175}}, + {{219, 219, 118, 173}}, {{220, 220, 127, 163}}, {{221, 221, 124, 161}}, + {{222, 222, 121, 167}}, {{223, 223, 122, 165}}, {{224, 224, 59, 219}}, + {{225, 225, 56, 217}}, {{226, 226, 61, 223}}, {{227, 227, 62, 221}}, + {{228, 228, 55, 211}}, {{229, 229, 52, 209}}, {{230, 230, 49, 215}}, + {{231, 231, 50, 213}}, {{232, 232, 35, 203}}, {{233, 233, 32, 201}}, + {{234, 234, 37, 207}}, {{235, 235, 38, 205}}, {{236, 236, 47, 195}}, + {{237, 237, 44, 193}}, {{238, 238, 41, 199}}, {{239, 239, 42, 197}}, + {{240, 240, 11, 251}}, {{241, 241, 8, 249}}, {{242, 242, 13, 255}}, + {{243, 243, 14, 253}}, {{244, 244, 7, 243}}, {{245, 245, 4, 241}}, + {{246, 246, 1, 247}}, {{247, 247, 2, 245}}, {{248, 248, 19, 235}}, + {{249, 249, 16, 233}}, {{250, 250, 21, 239}}, {{251, 251, 22, 237}}, + {{252, 252, 31, 227}}, {{253, 253, 28, 225}}, {{254, 254, 25, 231}}, + {{255, 255, 26, 229}}, + }, +}; + +const word8x4 M1[4][256] = { + { + {{ 0, 0, 0, 0}}, {{ 14, 9, 13, 11}}, {{ 28, 18, 26, 22}}, + {{ 18, 27, 23, 29}}, {{ 56, 36, 52, 44}}, {{ 54, 45, 57, 39}}, + {{ 36, 54, 46, 58}}, {{ 42, 63, 35, 49}}, {{112, 72, 104, 88}}, + {{126, 65, 101, 83}}, {{108, 90, 114, 78}}, {{ 98, 83, 127, 69}}, + {{ 72, 108, 92, 116}}, {{ 70, 101, 81, 127}}, {{ 84, 126, 70, 98}}, + {{ 90, 119, 75, 105}}, {{224, 144, 208, 176}}, {{238, 153, 221, 187}}, + {{252, 130, 202, 166}}, {{242, 139, 199, 173}}, {{216, 180, 228, 156}}, + {{214, 189, 233, 151}}, {{196, 166, 254, 138}}, {{202, 175, 243, 129}}, + {{144, 216, 184, 232}}, {{158, 209, 181, 227}}, {{140, 202, 162, 254}}, + {{130, 195, 175, 245}}, {{168, 252, 140, 196}}, {{166, 245, 129, 207}}, + {{180, 238, 150, 210}}, {{186, 231, 155, 217}}, {{219, 59, 187, 123}}, + {{213, 50, 182, 112}}, {{199, 41, 161, 109}}, {{201, 32, 172, 102}}, + {{227, 31, 143, 87}}, {{237, 22, 130, 92}}, {{255, 13, 149, 65}}, + {{241, 4, 152, 74}}, {{171, 115, 211, 35}}, {{165, 122, 222, 40}}, + {{183, 97, 201, 53}}, {{185, 104, 196, 62}}, {{147, 87, 231, 15}}, + {{157, 94, 234, 4}}, {{143, 69, 253, 25}}, {{129, 76, 240, 18}}, + {{ 59, 171, 107, 203}}, {{ 53, 162, 102, 192}}, {{ 39, 185, 113, 221}}, + {{ 41, 176, 124, 214}}, {{ 3, 143, 95, 231}}, {{ 13, 134, 82, 236}}, + {{ 31, 157, 69, 241}}, {{ 17, 148, 72, 250}}, {{ 75, 227, 3, 147}}, + {{ 69, 234, 14, 152}}, {{ 87, 241, 25, 133}}, {{ 89, 248, 20, 142}}, + {{115, 199, 55, 191}}, {{125, 206, 58, 180}}, {{111, 213, 45, 169}}, + {{ 97, 220, 32, 162}}, {{173, 118, 109, 246}}, {{163, 127, 96, 253}}, + {{177, 100, 119, 224}}, {{191, 109, 122, 235}}, {{149, 82, 89, 218}}, + {{155, 91, 84, 209}}, {{137, 64, 67, 204}}, {{135, 73, 78, 199}}, + {{221, 62, 5, 174}}, {{211, 55, 8, 165}}, {{193, 44, 31, 184}}, + {{207, 37, 18, 179}}, {{229, 26, 49, 130}}, {{235, 19, 60, 137}}, + {{249, 8, 43, 148}}, {{247, 1, 38, 159}}, {{ 77, 230, 189, 70}}, + {{ 67, 239, 176, 77}}, {{ 81, 244, 167, 80}}, {{ 95, 253, 170, 91}}, + {{117, 194, 137, 106}}, {{123, 203, 132, 97}}, {{105, 208, 147, 124}}, + {{103, 217, 158, 119}}, {{ 61, 174, 213, 30}}, {{ 51, 167, 216, 21}}, + {{ 33, 188, 207, 8}}, {{ 47, 181, 194, 3}}, {{ 5, 138, 225, 50}}, + {{ 11, 131, 236, 57}}, {{ 25, 152, 251, 36}}, {{ 23, 145, 246, 47}}, + {{118, 77, 214, 141}}, {{120, 68, 219, 134}}, {{106, 95, 204, 155}}, + {{100, 86, 193, 144}}, {{ 78, 105, 226, 161}}, {{ 64, 96, 239, 170}}, + {{ 82, 123, 248, 183}}, {{ 92, 114, 245, 188}}, {{ 6, 5, 190, 213}}, + {{ 8, 12, 179, 222}}, {{ 26, 23, 164, 195}}, {{ 20, 30, 169, 200}}, + {{ 62, 33, 138, 249}}, {{ 48, 40, 135, 242}}, {{ 34, 51, 144, 239}}, + {{ 44, 58, 157, 228}}, {{150, 221, 6, 61}}, {{152, 212, 11, 54}}, + {{138, 207, 28, 43}}, {{132, 198, 17, 32}}, {{174, 249, 50, 17}}, + {{160, 240, 63, 26}}, {{178, 235, 40, 7}}, {{188, 226, 37, 12}}, + {{230, 149, 110, 101}}, {{232, 156, 99, 110}}, {{250, 135, 116, 115}}, + {{244, 142, 121, 120}}, {{222, 177, 90, 73}}, {{208, 184, 87, 66}}, + {{194, 163, 64, 95}}, {{204, 170, 77, 84}}, {{ 65, 236, 218, 247}}, + {{ 79, 229, 215, 252}}, {{ 93, 254, 192, 225}}, {{ 83, 247, 205, 234}}, + {{121, 200, 238, 219}}, {{119, 193, 227, 208}}, {{101, 218, 244, 205}}, + {{107, 211, 249, 198}}, {{ 49, 164, 178, 175}}, {{ 63, 173, 191, 164}}, + {{ 45, 182, 168, 185}}, {{ 35, 191, 165, 178}}, {{ 9, 128, 134, 131}}, + {{ 7, 137, 139, 136}}, {{ 21, 146, 156, 149}}, {{ 27, 155, 145, 158}}, + {{161, 124, 10, 71}}, {{175, 117, 7, 76}}, {{189, 110, 16, 81}}, + {{179, 103, 29, 90}}, {{153, 88, 62, 107}}, {{151, 81, 51, 96}}, + {{133, 74, 36, 125}}, {{139, 67, 41, 118}}, {{209, 52, 98, 31}}, + {{223, 61, 111, 20}}, {{205, 38, 120, 9}}, {{195, 47, 117, 2}}, + {{233, 16, 86, 51}}, {{231, 25, 91, 56}}, {{245, 2, 76, 37}}, + {{251, 11, 65, 46}}, {{154, 215, 97, 140}}, {{148, 222, 108, 135}}, + {{134, 197, 123, 154}}, {{136, 204, 118, 145}}, {{162, 243, 85, 160}}, + {{172, 250, 88, 171}}, {{190, 225, 79, 182}}, {{176, 232, 66, 189}}, + {{234, 159, 9, 212}}, {{228, 150, 4, 223}}, {{246, 141, 19, 194}}, + {{248, 132, 30, 201}}, {{210, 187, 61, 248}}, {{220, 178, 48, 243}}, + {{206, 169, 39, 238}}, {{192, 160, 42, 229}}, {{122, 71, 177, 60}}, + {{116, 78, 188, 55}}, {{102, 85, 171, 42}}, {{104, 92, 166, 33}}, + {{ 66, 99, 133, 16}}, {{ 76, 106, 136, 27}}, {{ 94, 113, 159, 6}}, + {{ 80, 120, 146, 13}}, {{ 10, 15, 217, 100}}, {{ 4, 6, 212, 111}}, + {{ 22, 29, 195, 114}}, {{ 24, 20, 206, 121}}, {{ 50, 43, 237, 72}}, + {{ 60, 34, 224, 67}}, {{ 46, 57, 247, 94}}, {{ 32, 48, 250, 85}}, + {{236, 154, 183, 1}}, {{226, 147, 186, 10}}, {{240, 136, 173, 23}}, + {{254, 129, 160, 28}}, {{212, 190, 131, 45}}, {{218, 183, 142, 38}}, + {{200, 172, 153, 59}}, {{198, 165, 148, 48}}, {{156, 210, 223, 89}}, + {{146, 219, 210, 82}}, {{128, 192, 197, 79}}, {{142, 201, 200, 68}}, + {{164, 246, 235, 117}}, {{170, 255, 230, 126}}, {{184, 228, 241, 99}}, + {{182, 237, 252, 104}}, {{ 12, 10, 103, 177}}, {{ 2, 3, 106, 186}}, + {{ 16, 24, 125, 167}}, {{ 30, 17, 112, 172}}, {{ 52, 46, 83, 157}}, + {{ 58, 39, 94, 150}}, {{ 40, 60, 73, 139}}, {{ 38, 53, 68, 128}}, + {{124, 66, 15, 233}}, {{114, 75, 2, 226}}, {{ 96, 80, 21, 255}}, + {{110, 89, 24, 244}}, {{ 68, 102, 59, 197}}, {{ 74, 111, 54, 206}}, + {{ 88, 116, 33, 211}}, {{ 86, 125, 44, 216}}, {{ 55, 161, 12, 122}}, + {{ 57, 168, 1, 113}}, {{ 43, 179, 22, 108}}, {{ 37, 186, 27, 103}}, + {{ 15, 133, 56, 86}}, {{ 1, 140, 53, 93}}, {{ 19, 151, 34, 64}}, + {{ 29, 158, 47, 75}}, {{ 71, 233, 100, 34}}, {{ 73, 224, 105, 41}}, + {{ 91, 251, 126, 52}}, {{ 85, 242, 115, 63}}, {{127, 205, 80, 14}}, + {{113, 196, 93, 5}}, {{ 99, 223, 74, 24}}, {{109, 214, 71, 19}}, + {{215, 49, 220, 202}}, {{217, 56, 209, 193}}, {{203, 35, 198, 220}}, + {{197, 42, 203, 215}}, {{239, 21, 232, 230}}, {{225, 28, 229, 237}}, + {{243, 7, 242, 240}}, {{253, 14, 255, 251}}, {{167, 121, 180, 146}}, + {{169, 112, 185, 153}}, {{187, 107, 174, 132}}, {{181, 98, 163, 143}}, + {{159, 93, 128, 190}}, {{145, 84, 141, 181}}, {{131, 79, 154, 168}}, + {{141, 70, 151, 163}}, + }, + { + {{ 0, 0, 0, 0}}, {{ 11, 14, 9, 13}}, {{ 22, 28, 18, 26}}, + {{ 29, 18, 27, 23}}, {{ 44, 56, 36, 52}}, {{ 39, 54, 45, 57}}, + {{ 58, 36, 54, 46}}, {{ 49, 42, 63, 35}}, {{ 88, 112, 72, 104}}, + {{ 83, 126, 65, 101}}, {{ 78, 108, 90, 114}}, {{ 69, 98, 83, 127}}, + {{116, 72, 108, 92}}, {{127, 70, 101, 81}}, {{ 98, 84, 126, 70}}, + {{105, 90, 119, 75}}, {{176, 224, 144, 208}}, {{187, 238, 153, 221}}, + {{166, 252, 130, 202}}, {{173, 242, 139, 199}}, {{156, 216, 180, 228}}, + {{151, 214, 189, 233}}, {{138, 196, 166, 254}}, {{129, 202, 175, 243}}, + {{232, 144, 216, 184}}, {{227, 158, 209, 181}}, {{254, 140, 202, 162}}, + {{245, 130, 195, 175}}, {{196, 168, 252, 140}}, {{207, 166, 245, 129}}, + {{210, 180, 238, 150}}, {{217, 186, 231, 155}}, {{123, 219, 59, 187}}, + {{112, 213, 50, 182}}, {{109, 199, 41, 161}}, {{102, 201, 32, 172}}, + {{ 87, 227, 31, 143}}, {{ 92, 237, 22, 130}}, {{ 65, 255, 13, 149}}, + {{ 74, 241, 4, 152}}, {{ 35, 171, 115, 211}}, {{ 40, 165, 122, 222}}, + {{ 53, 183, 97, 201}}, {{ 62, 185, 104, 196}}, {{ 15, 147, 87, 231}}, + {{ 4, 157, 94, 234}}, {{ 25, 143, 69, 253}}, {{ 18, 129, 76, 240}}, + {{203, 59, 171, 107}}, {{192, 53, 162, 102}}, {{221, 39, 185, 113}}, + {{214, 41, 176, 124}}, {{231, 3, 143, 95}}, {{236, 13, 134, 82}}, + {{241, 31, 157, 69}}, {{250, 17, 148, 72}}, {{147, 75, 227, 3}}, + {{152, 69, 234, 14}}, {{133, 87, 241, 25}}, {{142, 89, 248, 20}}, + {{191, 115, 199, 55}}, {{180, 125, 206, 58}}, {{169, 111, 213, 45}}, + {{162, 97, 220, 32}}, {{246, 173, 118, 109}}, {{253, 163, 127, 96}}, + {{224, 177, 100, 119}}, {{235, 191, 109, 122}}, {{218, 149, 82, 89}}, + {{209, 155, 91, 84}}, {{204, 137, 64, 67}}, {{199, 135, 73, 78}}, + {{174, 221, 62, 5}}, {{165, 211, 55, 8}}, {{184, 193, 44, 31}}, + {{179, 207, 37, 18}}, {{130, 229, 26, 49}}, {{137, 235, 19, 60}}, + {{148, 249, 8, 43}}, {{159, 247, 1, 38}}, {{ 70, 77, 230, 189}}, + {{ 77, 67, 239, 176}}, {{ 80, 81, 244, 167}}, {{ 91, 95, 253, 170}}, + {{106, 117, 194, 137}}, {{ 97, 123, 203, 132}}, {{124, 105, 208, 147}}, + {{119, 103, 217, 158}}, {{ 30, 61, 174, 213}}, {{ 21, 51, 167, 216}}, + {{ 8, 33, 188, 207}}, {{ 3, 47, 181, 194}}, {{ 50, 5, 138, 225}}, + {{ 57, 11, 131, 236}}, {{ 36, 25, 152, 251}}, {{ 47, 23, 145, 246}}, + {{141, 118, 77, 214}}, {{134, 120, 68, 219}}, {{155, 106, 95, 204}}, + {{144, 100, 86, 193}}, {{161, 78, 105, 226}}, {{170, 64, 96, 239}}, + {{183, 82, 123, 248}}, {{188, 92, 114, 245}}, {{213, 6, 5, 190}}, + {{222, 8, 12, 179}}, {{195, 26, 23, 164}}, {{200, 20, 30, 169}}, + {{249, 62, 33, 138}}, {{242, 48, 40, 135}}, {{239, 34, 51, 144}}, + {{228, 44, 58, 157}}, {{ 61, 150, 221, 6}}, {{ 54, 152, 212, 11}}, + {{ 43, 138, 207, 28}}, {{ 32, 132, 198, 17}}, {{ 17, 174, 249, 50}}, + {{ 26, 160, 240, 63}}, {{ 7, 178, 235, 40}}, {{ 12, 188, 226, 37}}, + {{101, 230, 149, 110}}, {{110, 232, 156, 99}}, {{115, 250, 135, 116}}, + {{120, 244, 142, 121}}, {{ 73, 222, 177, 90}}, {{ 66, 208, 184, 87}}, + {{ 95, 194, 163, 64}}, {{ 84, 204, 170, 77}}, {{247, 65, 236, 218}}, + {{252, 79, 229, 215}}, {{225, 93, 254, 192}}, {{234, 83, 247, 205}}, + {{219, 121, 200, 238}}, {{208, 119, 193, 227}}, {{205, 101, 218, 244}}, + {{198, 107, 211, 249}}, {{175, 49, 164, 178}}, {{164, 63, 173, 191}}, + {{185, 45, 182, 168}}, {{178, 35, 191, 165}}, {{131, 9, 128, 134}}, + {{136, 7, 137, 139}}, {{149, 21, 146, 156}}, {{158, 27, 155, 145}}, + {{ 71, 161, 124, 10}}, {{ 76, 175, 117, 7}}, {{ 81, 189, 110, 16}}, + {{ 90, 179, 103, 29}}, {{107, 153, 88, 62}}, {{ 96, 151, 81, 51}}, + {{125, 133, 74, 36}}, {{118, 139, 67, 41}}, {{ 31, 209, 52, 98}}, + {{ 20, 223, 61, 111}}, {{ 9, 205, 38, 120}}, {{ 2, 195, 47, 117}}, + {{ 51, 233, 16, 86}}, {{ 56, 231, 25, 91}}, {{ 37, 245, 2, 76}}, + {{ 46, 251, 11, 65}}, {{140, 154, 215, 97}}, {{135, 148, 222, 108}}, + {{154, 134, 197, 123}}, {{145, 136, 204, 118}}, {{160, 162, 243, 85}}, + {{171, 172, 250, 88}}, {{182, 190, 225, 79}}, {{189, 176, 232, 66}}, + {{212, 234, 159, 9}}, {{223, 228, 150, 4}}, {{194, 246, 141, 19}}, + {{201, 248, 132, 30}}, {{248, 210, 187, 61}}, {{243, 220, 178, 48}}, + {{238, 206, 169, 39}}, {{229, 192, 160, 42}}, {{ 60, 122, 71, 177}}, + {{ 55, 116, 78, 188}}, {{ 42, 102, 85, 171}}, {{ 33, 104, 92, 166}}, + {{ 16, 66, 99, 133}}, {{ 27, 76, 106, 136}}, {{ 6, 94, 113, 159}}, + {{ 13, 80, 120, 146}}, {{100, 10, 15, 217}}, {{111, 4, 6, 212}}, + {{114, 22, 29, 195}}, {{121, 24, 20, 206}}, {{ 72, 50, 43, 237}}, + {{ 67, 60, 34, 224}}, {{ 94, 46, 57, 247}}, {{ 85, 32, 48, 250}}, + {{ 1, 236, 154, 183}}, {{ 10, 226, 147, 186}}, {{ 23, 240, 136, 173}}, + {{ 28, 254, 129, 160}}, {{ 45, 212, 190, 131}}, {{ 38, 218, 183, 142}}, + {{ 59, 200, 172, 153}}, {{ 48, 198, 165, 148}}, {{ 89, 156, 210, 223}}, + {{ 82, 146, 219, 210}}, {{ 79, 128, 192, 197}}, {{ 68, 142, 201, 200}}, + {{117, 164, 246, 235}}, {{126, 170, 255, 230}}, {{ 99, 184, 228, 241}}, + {{104, 182, 237, 252}}, {{177, 12, 10, 103}}, {{186, 2, 3, 106}}, + {{167, 16, 24, 125}}, {{172, 30, 17, 112}}, {{157, 52, 46, 83}}, + {{150, 58, 39, 94}}, {{139, 40, 60, 73}}, {{128, 38, 53, 68}}, + {{233, 124, 66, 15}}, {{226, 114, 75, 2}}, {{255, 96, 80, 21}}, + {{244, 110, 89, 24}}, {{197, 68, 102, 59}}, {{206, 74, 111, 54}}, + {{211, 88, 116, 33}}, {{216, 86, 125, 44}}, {{122, 55, 161, 12}}, + {{113, 57, 168, 1}}, {{108, 43, 179, 22}}, {{103, 37, 186, 27}}, + {{ 86, 15, 133, 56}}, {{ 93, 1, 140, 53}}, {{ 64, 19, 151, 34}}, + {{ 75, 29, 158, 47}}, {{ 34, 71, 233, 100}}, {{ 41, 73, 224, 105}}, + {{ 52, 91, 251, 126}}, {{ 63, 85, 242, 115}}, {{ 14, 127, 205, 80}}, + {{ 5, 113, 196, 93}}, {{ 24, 99, 223, 74}}, {{ 19, 109, 214, 71}}, + {{202, 215, 49, 220}}, {{193, 217, 56, 209}}, {{220, 203, 35, 198}}, + {{215, 197, 42, 203}}, {{230, 239, 21, 232}}, {{237, 225, 28, 229}}, + {{240, 243, 7, 242}}, {{251, 253, 14, 255}}, {{146, 167, 121, 180}}, + {{153, 169, 112, 185}}, {{132, 187, 107, 174}}, {{143, 181, 98, 163}}, + {{190, 159, 93, 128}}, {{181, 145, 84, 141}}, {{168, 131, 79, 154}}, + {{163, 141, 70, 151}}, + }, + { + {{ 0, 0, 0, 0}}, {{ 13, 11, 14, 9}}, {{ 26, 22, 28, 18}}, + {{ 23, 29, 18, 27}}, {{ 52, 44, 56, 36}}, {{ 57, 39, 54, 45}}, + {{ 46, 58, 36, 54}}, {{ 35, 49, 42, 63}}, {{104, 88, 112, 72}}, + {{101, 83, 126, 65}}, {{114, 78, 108, 90}}, {{127, 69, 98, 83}}, + {{ 92, 116, 72, 108}}, {{ 81, 127, 70, 101}}, {{ 70, 98, 84, 126}}, + {{ 75, 105, 90, 119}}, {{208, 176, 224, 144}}, {{221, 187, 238, 153}}, + {{202, 166, 252, 130}}, {{199, 173, 242, 139}}, {{228, 156, 216, 180}}, + {{233, 151, 214, 189}}, {{254, 138, 196, 166}}, {{243, 129, 202, 175}}, + {{184, 232, 144, 216}}, {{181, 227, 158, 209}}, {{162, 254, 140, 202}}, + {{175, 245, 130, 195}}, {{140, 196, 168, 252}}, {{129, 207, 166, 245}}, + {{150, 210, 180, 238}}, {{155, 217, 186, 231}}, {{187, 123, 219, 59}}, + {{182, 112, 213, 50}}, {{161, 109, 199, 41}}, {{172, 102, 201, 32}}, + {{143, 87, 227, 31}}, {{130, 92, 237, 22}}, {{149, 65, 255, 13}}, + {{152, 74, 241, 4}}, {{211, 35, 171, 115}}, {{222, 40, 165, 122}}, + {{201, 53, 183, 97}}, {{196, 62, 185, 104}}, {{231, 15, 147, 87}}, + {{234, 4, 157, 94}}, {{253, 25, 143, 69}}, {{240, 18, 129, 76}}, + {{107, 203, 59, 171}}, {{102, 192, 53, 162}}, {{113, 221, 39, 185}}, + {{124, 214, 41, 176}}, {{ 95, 231, 3, 143}}, {{ 82, 236, 13, 134}}, + {{ 69, 241, 31, 157}}, {{ 72, 250, 17, 148}}, {{ 3, 147, 75, 227}}, + {{ 14, 152, 69, 234}}, {{ 25, 133, 87, 241}}, {{ 20, 142, 89, 248}}, + {{ 55, 191, 115, 199}}, {{ 58, 180, 125, 206}}, {{ 45, 169, 111, 213}}, + {{ 32, 162, 97, 220}}, {{109, 246, 173, 118}}, {{ 96, 253, 163, 127}}, + {{119, 224, 177, 100}}, {{122, 235, 191, 109}}, {{ 89, 218, 149, 82}}, + {{ 84, 209, 155, 91}}, {{ 67, 204, 137, 64}}, {{ 78, 199, 135, 73}}, + {{ 5, 174, 221, 62}}, {{ 8, 165, 211, 55}}, {{ 31, 184, 193, 44}}, + {{ 18, 179, 207, 37}}, {{ 49, 130, 229, 26}}, {{ 60, 137, 235, 19}}, + {{ 43, 148, 249, 8}}, {{ 38, 159, 247, 1}}, {{189, 70, 77, 230}}, + {{176, 77, 67, 239}}, {{167, 80, 81, 244}}, {{170, 91, 95, 253}}, + {{137, 106, 117, 194}}, {{132, 97, 123, 203}}, {{147, 124, 105, 208}}, + {{158, 119, 103, 217}}, {{213, 30, 61, 174}}, {{216, 21, 51, 167}}, + {{207, 8, 33, 188}}, {{194, 3, 47, 181}}, {{225, 50, 5, 138}}, + {{236, 57, 11, 131}}, {{251, 36, 25, 152}}, {{246, 47, 23, 145}}, + {{214, 141, 118, 77}}, {{219, 134, 120, 68}}, {{204, 155, 106, 95}}, + {{193, 144, 100, 86}}, {{226, 161, 78, 105}}, {{239, 170, 64, 96}}, + {{248, 183, 82, 123}}, {{245, 188, 92, 114}}, {{190, 213, 6, 5}}, + {{179, 222, 8, 12}}, {{164, 195, 26, 23}}, {{169, 200, 20, 30}}, + {{138, 249, 62, 33}}, {{135, 242, 48, 40}}, {{144, 239, 34, 51}}, + {{157, 228, 44, 58}}, {{ 6, 61, 150, 221}}, {{ 11, 54, 152, 212}}, + {{ 28, 43, 138, 207}}, {{ 17, 32, 132, 198}}, {{ 50, 17, 174, 249}}, + {{ 63, 26, 160, 240}}, {{ 40, 7, 178, 235}}, {{ 37, 12, 188, 226}}, + {{110, 101, 230, 149}}, {{ 99, 110, 232, 156}}, {{116, 115, 250, 135}}, + {{121, 120, 244, 142}}, {{ 90, 73, 222, 177}}, {{ 87, 66, 208, 184}}, + {{ 64, 95, 194, 163}}, {{ 77, 84, 204, 170}}, {{218, 247, 65, 236}}, + {{215, 252, 79, 229}}, {{192, 225, 93, 254}}, {{205, 234, 83, 247}}, + {{238, 219, 121, 200}}, {{227, 208, 119, 193}}, {{244, 205, 101, 218}}, + {{249, 198, 107, 211}}, {{178, 175, 49, 164}}, {{191, 164, 63, 173}}, + {{168, 185, 45, 182}}, {{165, 178, 35, 191}}, {{134, 131, 9, 128}}, + {{139, 136, 7, 137}}, {{156, 149, 21, 146}}, {{145, 158, 27, 155}}, + {{ 10, 71, 161, 124}}, {{ 7, 76, 175, 117}}, {{ 16, 81, 189, 110}}, + {{ 29, 90, 179, 103}}, {{ 62, 107, 153, 88}}, {{ 51, 96, 151, 81}}, + {{ 36, 125, 133, 74}}, {{ 41, 118, 139, 67}}, {{ 98, 31, 209, 52}}, + {{111, 20, 223, 61}}, {{120, 9, 205, 38}}, {{117, 2, 195, 47}}, + {{ 86, 51, 233, 16}}, {{ 91, 56, 231, 25}}, {{ 76, 37, 245, 2}}, + {{ 65, 46, 251, 11}}, {{ 97, 140, 154, 215}}, {{108, 135, 148, 222}}, + {{123, 154, 134, 197}}, {{118, 145, 136, 204}}, {{ 85, 160, 162, 243}}, + {{ 88, 171, 172, 250}}, {{ 79, 182, 190, 225}}, {{ 66, 189, 176, 232}}, + {{ 9, 212, 234, 159}}, {{ 4, 223, 228, 150}}, {{ 19, 194, 246, 141}}, + {{ 30, 201, 248, 132}}, {{ 61, 248, 210, 187}}, {{ 48, 243, 220, 178}}, + {{ 39, 238, 206, 169}}, {{ 42, 229, 192, 160}}, {{177, 60, 122, 71}}, + {{188, 55, 116, 78}}, {{171, 42, 102, 85}}, {{166, 33, 104, 92}}, + {{133, 16, 66, 99}}, {{136, 27, 76, 106}}, {{159, 6, 94, 113}}, + {{146, 13, 80, 120}}, {{217, 100, 10, 15}}, {{212, 111, 4, 6}}, + {{195, 114, 22, 29}}, {{206, 121, 24, 20}}, {{237, 72, 50, 43}}, + {{224, 67, 60, 34}}, {{247, 94, 46, 57}}, {{250, 85, 32, 48}}, + {{183, 1, 236, 154}}, {{186, 10, 226, 147}}, {{173, 23, 240, 136}}, + {{160, 28, 254, 129}}, {{131, 45, 212, 190}}, {{142, 38, 218, 183}}, + {{153, 59, 200, 172}}, {{148, 48, 198, 165}}, {{223, 89, 156, 210}}, + {{210, 82, 146, 219}}, {{197, 79, 128, 192}}, {{200, 68, 142, 201}}, + {{235, 117, 164, 246}}, {{230, 126, 170, 255}}, {{241, 99, 184, 228}}, + {{252, 104, 182, 237}}, {{103, 177, 12, 10}}, {{106, 186, 2, 3}}, + {{125, 167, 16, 24}}, {{112, 172, 30, 17}}, {{ 83, 157, 52, 46}}, + {{ 94, 150, 58, 39}}, {{ 73, 139, 40, 60}}, {{ 68, 128, 38, 53}}, + {{ 15, 233, 124, 66}}, {{ 2, 226, 114, 75}}, {{ 21, 255, 96, 80}}, + {{ 24, 244, 110, 89}}, {{ 59, 197, 68, 102}}, {{ 54, 206, 74, 111}}, + {{ 33, 211, 88, 116}}, {{ 44, 216, 86, 125}}, {{ 12, 122, 55, 161}}, + {{ 1, 113, 57, 168}}, {{ 22, 108, 43, 179}}, {{ 27, 103, 37, 186}}, + {{ 56, 86, 15, 133}}, {{ 53, 93, 1, 140}}, {{ 34, 64, 19, 151}}, + {{ 47, 75, 29, 158}}, {{100, 34, 71, 233}}, {{105, 41, 73, 224}}, + {{126, 52, 91, 251}}, {{115, 63, 85, 242}}, {{ 80, 14, 127, 205}}, + {{ 93, 5, 113, 196}}, {{ 74, 24, 99, 223}}, {{ 71, 19, 109, 214}}, + {{220, 202, 215, 49}}, {{209, 193, 217, 56}}, {{198, 220, 203, 35}}, + {{203, 215, 197, 42}}, {{232, 230, 239, 21}}, {{229, 237, 225, 28}}, + {{242, 240, 243, 7}}, {{255, 251, 253, 14}}, {{180, 146, 167, 121}}, + {{185, 153, 169, 112}}, {{174, 132, 187, 107}}, {{163, 143, 181, 98}}, + {{128, 190, 159, 93}}, {{141, 181, 145, 84}}, {{154, 168, 131, 79}}, + {{151, 163, 141, 70}}, + }, + { + {{ 0, 0, 0, 0}}, {{ 9, 13, 11, 14}}, {{ 18, 26, 22, 28}}, + {{ 27, 23, 29, 18}}, {{ 36, 52, 44, 56}}, {{ 45, 57, 39, 54}}, + {{ 54, 46, 58, 36}}, {{ 63, 35, 49, 42}}, {{ 72, 104, 88, 112}}, + {{ 65, 101, 83, 126}}, {{ 90, 114, 78, 108}}, {{ 83, 127, 69, 98}}, + {{108, 92, 116, 72}}, {{101, 81, 127, 70}}, {{126, 70, 98, 84}}, + {{119, 75, 105, 90}}, {{144, 208, 176, 224}}, {{153, 221, 187, 238}}, + {{130, 202, 166, 252}}, {{139, 199, 173, 242}}, {{180, 228, 156, 216}}, + {{189, 233, 151, 214}}, {{166, 254, 138, 196}}, {{175, 243, 129, 202}}, + {{216, 184, 232, 144}}, {{209, 181, 227, 158}}, {{202, 162, 254, 140}}, + {{195, 175, 245, 130}}, {{252, 140, 196, 168}}, {{245, 129, 207, 166}}, + {{238, 150, 210, 180}}, {{231, 155, 217, 186}}, {{ 59, 187, 123, 219}}, + {{ 50, 182, 112, 213}}, {{ 41, 161, 109, 199}}, {{ 32, 172, 102, 201}}, + {{ 31, 143, 87, 227}}, {{ 22, 130, 92, 237}}, {{ 13, 149, 65, 255}}, + {{ 4, 152, 74, 241}}, {{115, 211, 35, 171}}, {{122, 222, 40, 165}}, + {{ 97, 201, 53, 183}}, {{104, 196, 62, 185}}, {{ 87, 231, 15, 147}}, + {{ 94, 234, 4, 157}}, {{ 69, 253, 25, 143}}, {{ 76, 240, 18, 129}}, + {{171, 107, 203, 59}}, {{162, 102, 192, 53}}, {{185, 113, 221, 39}}, + {{176, 124, 214, 41}}, {{143, 95, 231, 3}}, {{134, 82, 236, 13}}, + {{157, 69, 241, 31}}, {{148, 72, 250, 17}}, {{227, 3, 147, 75}}, + {{234, 14, 152, 69}}, {{241, 25, 133, 87}}, {{248, 20, 142, 89}}, + {{199, 55, 191, 115}}, {{206, 58, 180, 125}}, {{213, 45, 169, 111}}, + {{220, 32, 162, 97}}, {{118, 109, 246, 173}}, {{127, 96, 253, 163}}, + {{100, 119, 224, 177}}, {{109, 122, 235, 191}}, {{ 82, 89, 218, 149}}, + {{ 91, 84, 209, 155}}, {{ 64, 67, 204, 137}}, {{ 73, 78, 199, 135}}, + {{ 62, 5, 174, 221}}, {{ 55, 8, 165, 211}}, {{ 44, 31, 184, 193}}, + {{ 37, 18, 179, 207}}, {{ 26, 49, 130, 229}}, {{ 19, 60, 137, 235}}, + {{ 8, 43, 148, 249}}, {{ 1, 38, 159, 247}}, {{230, 189, 70, 77}}, + {{239, 176, 77, 67}}, {{244, 167, 80, 81}}, {{253, 170, 91, 95}}, + {{194, 137, 106, 117}}, {{203, 132, 97, 123}}, {{208, 147, 124, 105}}, + {{217, 158, 119, 103}}, {{174, 213, 30, 61}}, {{167, 216, 21, 51}}, + {{188, 207, 8, 33}}, {{181, 194, 3, 47}}, {{138, 225, 50, 5}}, + {{131, 236, 57, 11}}, {{152, 251, 36, 25}}, {{145, 246, 47, 23}}, + {{ 77, 214, 141, 118}}, {{ 68, 219, 134, 120}}, {{ 95, 204, 155, 106}}, + {{ 86, 193, 144, 100}}, {{105, 226, 161, 78}}, {{ 96, 239, 170, 64}}, + {{123, 248, 183, 82}}, {{114, 245, 188, 92}}, {{ 5, 190, 213, 6}}, + {{ 12, 179, 222, 8}}, {{ 23, 164, 195, 26}}, {{ 30, 169, 200, 20}}, + {{ 33, 138, 249, 62}}, {{ 40, 135, 242, 48}}, {{ 51, 144, 239, 34}}, + {{ 58, 157, 228, 44}}, {{221, 6, 61, 150}}, {{212, 11, 54, 152}}, + {{207, 28, 43, 138}}, {{198, 17, 32, 132}}, {{249, 50, 17, 174}}, + {{240, 63, 26, 160}}, {{235, 40, 7, 178}}, {{226, 37, 12, 188}}, + {{149, 110, 101, 230}}, {{156, 99, 110, 232}}, {{135, 116, 115, 250}}, + {{142, 121, 120, 244}}, {{177, 90, 73, 222}}, {{184, 87, 66, 208}}, + {{163, 64, 95, 194}}, {{170, 77, 84, 204}}, {{236, 218, 247, 65}}, + {{229, 215, 252, 79}}, {{254, 192, 225, 93}}, {{247, 205, 234, 83}}, + {{200, 238, 219, 121}}, {{193, 227, 208, 119}}, {{218, 244, 205, 101}}, + {{211, 249, 198, 107}}, {{164, 178, 175, 49}}, {{173, 191, 164, 63}}, + {{182, 168, 185, 45}}, {{191, 165, 178, 35}}, {{128, 134, 131, 9}}, + {{137, 139, 136, 7}}, {{146, 156, 149, 21}}, {{155, 145, 158, 27}}, + {{124, 10, 71, 161}}, {{117, 7, 76, 175}}, {{110, 16, 81, 189}}, + {{103, 29, 90, 179}}, {{ 88, 62, 107, 153}}, {{ 81, 51, 96, 151}}, + {{ 74, 36, 125, 133}}, {{ 67, 41, 118, 139}}, {{ 52, 98, 31, 209}}, + {{ 61, 111, 20, 223}}, {{ 38, 120, 9, 205}}, {{ 47, 117, 2, 195}}, + {{ 16, 86, 51, 233}}, {{ 25, 91, 56, 231}}, {{ 2, 76, 37, 245}}, + {{ 11, 65, 46, 251}}, {{215, 97, 140, 154}}, {{222, 108, 135, 148}}, + {{197, 123, 154, 134}}, {{204, 118, 145, 136}}, {{243, 85, 160, 162}}, + {{250, 88, 171, 172}}, {{225, 79, 182, 190}}, {{232, 66, 189, 176}}, + {{159, 9, 212, 234}}, {{150, 4, 223, 228}}, {{141, 19, 194, 246}}, + {{132, 30, 201, 248}}, {{187, 61, 248, 210}}, {{178, 48, 243, 220}}, + {{169, 39, 238, 206}}, {{160, 42, 229, 192}}, {{ 71, 177, 60, 122}}, + {{ 78, 188, 55, 116}}, {{ 85, 171, 42, 102}}, {{ 92, 166, 33, 104}}, + {{ 99, 133, 16, 66}}, {{106, 136, 27, 76}}, {{113, 159, 6, 94}}, + {{120, 146, 13, 80}}, {{ 15, 217, 100, 10}}, {{ 6, 212, 111, 4}}, + {{ 29, 195, 114, 22}}, {{ 20, 206, 121, 24}}, {{ 43, 237, 72, 50}}, + {{ 34, 224, 67, 60}}, {{ 57, 247, 94, 46}}, {{ 48, 250, 85, 32}}, + {{154, 183, 1, 236}}, {{147, 186, 10, 226}}, {{136, 173, 23, 240}}, + {{129, 160, 28, 254}}, {{190, 131, 45, 212}}, {{183, 142, 38, 218}}, + {{172, 153, 59, 200}}, {{165, 148, 48, 198}}, {{210, 223, 89, 156}}, + {{219, 210, 82, 146}}, {{192, 197, 79, 128}}, {{201, 200, 68, 142}}, + {{246, 235, 117, 164}}, {{255, 230, 126, 170}}, {{228, 241, 99, 184}}, + {{237, 252, 104, 182}}, {{ 10, 103, 177, 12}}, {{ 3, 106, 186, 2}}, + {{ 24, 125, 167, 16}}, {{ 17, 112, 172, 30}}, {{ 46, 83, 157, 52}}, + {{ 39, 94, 150, 58}}, {{ 60, 73, 139, 40}}, {{ 53, 68, 128, 38}}, + {{ 66, 15, 233, 124}}, {{ 75, 2, 226, 114}}, {{ 80, 21, 255, 96}}, + {{ 89, 24, 244, 110}}, {{102, 59, 197, 68}}, {{111, 54, 206, 74}}, + {{116, 33, 211, 88}}, {{125, 44, 216, 86}}, {{161, 12, 122, 55}}, + {{168, 1, 113, 57}}, {{179, 22, 108, 43}}, {{186, 27, 103, 37}}, + {{133, 56, 86, 15}}, {{140, 53, 93, 1}}, {{151, 34, 64, 19}}, + {{158, 47, 75, 29}}, {{233, 100, 34, 71}}, {{224, 105, 41, 73}}, + {{251, 126, 52, 91}}, {{242, 115, 63, 85}}, {{205, 80, 14, 127}}, + {{196, 93, 5, 113}}, {{223, 74, 24, 99}}, {{214, 71, 19, 109}}, + {{ 49, 220, 202, 215}}, {{ 56, 209, 193, 217}}, {{ 35, 198, 220, 203}}, + {{ 42, 203, 215, 197}}, {{ 21, 232, 230, 239}}, {{ 28, 229, 237, 225}}, + {{ 7, 242, 240, 243}}, {{ 14, 255, 251, 253}}, {{121, 180, 146, 167}}, + {{112, 185, 153, 169}}, {{107, 174, 132, 187}}, {{ 98, 163, 143, 181}}, + {{ 93, 128, 190, 159}}, {{ 84, 141, 181, 145}}, {{ 79, 154, 168, 131}}, + {{ 70, 151, 163, 141}}, + }, +}; + +const int xrcon[30] = { + 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, + 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, + 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, +}; + +const word8 xS[256] = { + 99, 124, 119, 123, 242, 107, 111, 197, 48, 1, 103, 43, 254, 215, + 171, 118, 202, 130, 201, 125, 250, 89, 71, 240, 173, 212, 162, 175, + 156, 164, 114, 192, 183, 253, 147, 38, 54, 63, 247, 204, 52, 165, + 229, 241, 113, 216, 49, 21, 4, 199, 35, 195, 24, 150, 5, 154, + 7, 18, 128, 226, 235, 39, 178, 117, 9, 131, 44, 26, 27, 110, + 90, 160, 82, 59, 214, 179, 41, 227, 47, 132, 83, 209, 0, 237, + 32, 252, 177, 91, 106, 203, 190, 57, 74, 76, 88, 207, 208, 239, + 170, 251, 67, 77, 51, 133, 69, 249, 2, 127, 80, 60, 159, 168, + 81, 163, 64, 143, 146, 157, 56, 245, 188, 182, 218, 33, 16, 255, + 243, 210, 205, 12, 19, 236, 95, 151, 68, 23, 196, 167, 126, 61, + 100, 93, 25, 115, 96, 129, 79, 220, 34, 42, 144, 136, 70, 238, + 184, 20, 222, 94, 11, 219, 224, 50, 58, 10, 73, 6, 36, 92, + 194, 211, 172, 98, 145, 149, 228, 121, 231, 200, 55, 109, 141, 213, + 78, 169, 108, 86, 244, 234, 101, 122, 174, 8, 186, 120, 37, 46, + 28, 166, 180, 198, 232, 221, 116, 31, 75, 189, 139, 138, 112, 62, + 181, 102, 72, 3, 246, 14, 97, 53, 87, 185, 134, 193, 29, 158, + 225, 248, 152, 17, 105, 217, 142, 148, 155, 30, 135, 233, 206, 85, + 40, 223, 140, 161, 137, 13, 191, 230, 66, 104, 65, 153, 45, 15, + 176, 84, 187, 22, +}; + +const word8 xSi[256] = { + 82, 9, 106, 213, 48, 54, 165, 56, 191, 64, 163, 158, 129, 243, + 215, 251, 124, 227, 57, 130, 155, 47, 255, 135, 52, 142, 67, 68, + 196, 222, 233, 203, 84, 123, 148, 50, 166, 194, 35, 61, 238, 76, + 149, 11, 66, 250, 195, 78, 8, 46, 161, 102, 40, 217, 36, 178, + 118, 91, 162, 73, 109, 139, 209, 37, 114, 248, 246, 100, 134, 104, + 152, 22, 212, 164, 92, 204, 93, 101, 182, 146, 108, 112, 72, 80, + 253, 237, 185, 218, 94, 21, 70, 87, 167, 141, 157, 132, 144, 216, + 171, 0, 140, 188, 211, 10, 247, 228, 88, 5, 184, 179, 69, 6, + 208, 44, 30, 143, 202, 63, 15, 2, 193, 175, 189, 3, 1, 19, + 138, 107, 58, 145, 17, 65, 79, 103, 220, 234, 151, 242, 207, 206, + 240, 180, 230, 115, 150, 172, 116, 34, 231, 173, 53, 133, 226, 249, + 55, 232, 28, 117, 223, 110, 71, 241, 26, 113, 29, 41, 197, 137, + 111, 183, 98, 14, 170, 24, 190, 27, 252, 86, 62, 75, 198, 210, + 121, 32, 154, 219, 192, 254, 120, 205, 90, 244, 31, 221, 168, 51, + 136, 7, 199, 49, 177, 18, 16, 89, 39, 128, 236, 95, 96, 81, + 127, 169, 25, 181, 74, 13, 45, 229, 122, 159, 147, 201, 156, 239, + 160, 224, 59, 77, 174, 42, 245, 176, 200, 235, 187, 60, 131, 83, + 153, 97, 23, 43, 4, 126, 186, 119, 214, 38, 225, 105, 20, 99, + 85, 33, 12, 125, +}; + diff --git a/src/aes/ao_aes_tables.h b/src/aes/ao_aes_tables.h new file mode 100644 index 00000000..73bcf3fb --- /dev/null +++ b/src/aes/ao_aes_tables.h @@ -0,0 +1,10 @@ +/* Copyright (C) 2000-2009 Peter Selinger. + This file is part of ccrypt. It is free software and it is covered + by the GNU general public license. See the file COPYING for details. */ + +extern const word8x4 M0[4][256]; +extern const word8x4 M1[4][256]; +extern const int xrcon[30]; +extern const word8 xS[256]; +extern const word8 xSi[256]; + diff --git a/src/core/ao_aes.h b/src/core/ao_aes.h index 7f67374d..ab3e367e 100644 --- a/src/core/ao_aes.h +++ b/src/core/ao_aes.h @@ -29,9 +29,11 @@ enum ao_aes_mode { }; #if HAS_AES +#ifdef SDCC void ao_aes_isr(void) __interrupt 4; #endif +#endif void ao_aes_set_mode(enum ao_aes_mode mode); diff --git a/src/core/ao_radio_cmac.c b/src/core/ao_radio_cmac.c index e263f0db..7a377002 100644 --- a/src/core/ao_radio_cmac.c +++ b/src/core/ao_radio_cmac.c @@ -121,7 +121,7 @@ radio_cmac_recv(uint8_t len, uint16_t timeout) __reentrant } ao_radio_cmac_rssi = (int16_t) (((int8_t) cmac_data[len + AO_CMAC_KEY_LEN]) >> 1) - 74; - if (!(cmac_data[len + AO_CMAC_KEY_LEN +1] & PKT_APPEND_STATUS_1_CRC_OK)) + if (!(cmac_data[len + AO_CMAC_KEY_LEN +1] & AO_RADIO_STATUS_CRC_OK)) return AO_RADIO_CMAC_CRC_ERROR; ao_config_get(); @@ -233,9 +233,9 @@ radio_cmac_recv_cmd(void) __reentrant static __xdata struct ao_launch_command command; static __xdata struct ao_launch_query query; -static pdata uint16_t launch_serial; -static pdata uint8_t launch_channel; -static pdata uint16_t tick_offset; +static __pdata uint16_t launch_serial; +static __pdata uint8_t launch_channel; +static __pdata uint16_t tick_offset; static void launch_args(void) __reentrant diff --git a/src/stm/Makefile.defs b/src/stm/Makefile.defs index 3edfa41d..04404cdc 100644 --- a/src/stm/Makefile.defs +++ b/src/stm/Makefile.defs @@ -1,4 +1,4 @@ -vpath % ../stm:../product:../drivers:../core:../util:../kalman:.. +vpath % ../stm:../product:../drivers:../core:../util:../kalman:../aes:.. vpath make-altitude ../util vpath make-kalman ../util vpath kalman.5c ../kalman -- cgit v1.2.3 From 843fcab46d633e5bb6959286adeb68e41a4c30a3 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 29 Jul 2012 19:44:56 -0700 Subject: altos: Add telefire-v0.1 Signed-off-by: Keith Packard --- src/Makefile | 3 +- src/cc1111/ao_adc.c | 20 ++++ src/cc1111/ao_arch.h | 12 --- src/cc1111/ao_pins.h | 12 +++ src/core/ao.h | 7 ++ src/core/ao_config.c | 3 + src/core/ao_storage.c | 1 + src/drivers/ao_74hc497.c | 40 +++++++ src/drivers/ao_74hc497.h | 27 +++++ src/drivers/ao_pad.c | 227 ++++++++++++++++++++++++++++++++++++++++ src/drivers/ao_pad.h | 67 ++++++++++++ src/drivers/ao_pca9922.c | 78 ++++++++++++++ src/telefire-v0.1/Makefile | 101 ++++++++++++++++++ src/telefire-v0.1/ao_pins.h | 94 +++++++++++++++++ src/telefire-v0.1/ao_telefire.c | 41 ++++++++ 15 files changed, 720 insertions(+), 13 deletions(-) create mode 100644 src/drivers/ao_74hc497.c create mode 100644 src/drivers/ao_74hc497.h create mode 100644 src/drivers/ao_pad.c create mode 100644 src/drivers/ao_pad.h create mode 100644 src/drivers/ao_pca9922.c create mode 100644 src/telefire-v0.1/Makefile create mode 100644 src/telefire-v0.1/ao_pins.h create mode 100644 src/telefire-v0.1/ao_telefire.c (limited to 'src') diff --git a/src/Makefile b/src/Makefile index 491618f6..99ea8f85 100644 --- a/src/Makefile +++ b/src/Makefile @@ -21,7 +21,8 @@ ifneq ($(shell which sdcc),) telebt-v0.0 telebt-v0.1 \ telemetrum-v0.1-sky telemetrum-v0.1-sirf \ telelaunch-v0.1 tidongle test \ - teleterra-v0.2 teleshield-v0.1 + teleterra-v0.2 teleshield-v0.1 \ + telefire-v0.1 endif ifneq ($(shell which avr-gcc),) diff --git a/src/cc1111/ao_adc.c b/src/cc1111/ao_adc.c index ce827e25..f7b52281 100644 --- a/src/cc1111/ao_adc.c +++ b/src/cc1111/ao_adc.c @@ -140,6 +140,15 @@ ao_adc_isr(void) __interrupt 1 } #endif /* telemini || telenano */ +#ifdef TELEFIRE_V_0_1 + a = (uint8_t __xdata *) (&ao_data_ring[ao_data_head].adc.sense[0] + sequence); + a[0] = ADCL; + a[1] = ADCH; + if (sequence < 5) + ADCCON3 = ADCCON3_EREF_VDD | ADCCON3_EDIV_512 | (sequence + 1); +#define GOT_ADC +#endif /* TELEFIRE_V_0_1 */ + #ifndef GOT_ADC #error No known ADC configuration set #endif @@ -157,9 +166,13 @@ ao_adc_dump(void) __reentrant { static __xdata struct ao_data packet; ao_data_get(&packet); +#ifndef AO_ADC_DUMP printf("tick: %5u accel: %5d pres: %5d temp: %5d batt: %5d drogue: %5d main: %5d\n", packet.tick, packet.adc.accel, packet.adc.pres, packet.adc.temp, packet.adc.v_batt, packet.adc.sense_d, packet.adc.sense_m); +#else + AO_ADC_DUMP(&packet); +#endif } __code struct ao_cmds ao_adc_cmds[] = { @@ -170,6 +183,11 @@ __code struct ao_cmds ao_adc_cmds[] = { void ao_adc_init(void) { +#ifdef AO_ADC_PINS + ADCCFG = AO_ADC_PINS; + +#else + #if IGNITE_ON_P2 /* TeleMetrum configuration */ ADCCFG = ((1 << 0) | /* acceleration */ @@ -190,6 +208,8 @@ ao_adc_init(void) (1 << 3)); /* battery voltage */ #endif +#endif /* else AO_ADC_PINS */ + /* enable interrupts */ ADCIF = 0; IEN0 |= IEN0_ADCIE; diff --git a/src/cc1111/ao_arch.h b/src/cc1111/ao_arch.h index 06b04b93..a97515a7 100644 --- a/src/cc1111/ao_arch.h +++ b/src/cc1111/ao_arch.h @@ -200,18 +200,6 @@ extern AO_ROMCONFIG_SYMBOL(0x00a6) uint32_t ao_radio_cal; #define ao_arch_critical(b) __critical { b } -struct ao_adc { - int16_t accel; /* accelerometer */ - int16_t pres; /* pressure sensor */ - int16_t temp; /* temperature sensor */ - int16_t v_batt; /* battery voltage */ - int16_t sense_d; /* drogue continuity sense */ - int16_t sense_m; /* main continuity sense */ -#if HAS_ACCEL_REF - uint16_t accel_ref; /* acceleration reference */ -#endif -}; - #define AO_DATA_RING 32 /* ao_button.c */ diff --git a/src/cc1111/ao_pins.h b/src/cc1111/ao_pins.h index fc6ed3ec..2f0e2884 100644 --- a/src/cc1111/ao_pins.h +++ b/src/cc1111/ao_pins.h @@ -560,4 +560,16 @@ #define AO_IGNITER_FIRE_TIME AO_MS_TO_TICKS(50) #define AO_IGNITER_CHARGE_TIME AO_MS_TO_TICKS(2000) +struct ao_adc { + int16_t accel; /* accelerometer */ + int16_t pres; /* pressure sensor */ + int16_t temp; /* temperature sensor */ + int16_t v_batt; /* battery voltage */ + int16_t sense_d; /* drogue continuity sense */ + int16_t sense_m; /* main continuity sense */ +#if HAS_ACCEL_REF + uint16_t accel_ref; /* acceleration reference */ +#endif +}; + #endif /* _AO_PINS_H_ */ diff --git a/src/core/ao.h b/src/core/ao.h index 65b9eb18..1032dd33 100644 --- a/src/core/ao.h +++ b/src/core/ao.h @@ -432,6 +432,7 @@ ao_gps_report_mega_init(void); * ao_telemetry_orig.c */ +#if LEGACY_MONITOR struct ao_adc_orig { uint16_t tick; /* tick when the sample was read */ int16_t accel; /* accelerometer */ @@ -489,6 +490,8 @@ struct ao_telemetry_tiny_recv { uint8_t status; }; +#endif /* LEGACY_MONITOR */ + /* Unfortunately, we've exposed the CC1111 rssi units as the 'usual' method * for reporting RSSI. So, now we use these values everywhere */ @@ -582,6 +585,8 @@ ao_radio_init(void); * ao_monitor.c */ +#if HAS_MONITOR + extern const char const * const ao_state_names[]; #define AO_MONITOR_RING 8 @@ -618,6 +623,8 @@ ao_monitor_enable(void); void ao_monitor_init(void) __reentrant; +#endif + /* * ao_stdio.c */ diff --git a/src/core/ao_config.c b/src/core/ao_config.c index e2095e65..f19dd9cd 100644 --- a/src/core/ao_config.c +++ b/src/core/ao_config.c @@ -17,8 +17,11 @@ #include "ao.h" #include "ao_log.h" +#include +#if HAS_FLIGHT #include #include +#endif __xdata struct ao_config ao_config; __pdata uint8_t ao_config_loaded; diff --git a/src/core/ao_storage.c b/src/core/ao_storage.c index b2dd435b..adf7e4d4 100644 --- a/src/core/ao_storage.c +++ b/src/core/ao_storage.c @@ -16,6 +16,7 @@ */ #include +#include uint8_t ao_storage_read(ao_pos_t pos, __xdata void *buf, uint16_t len) __reentrant diff --git a/src/drivers/ao_74hc497.c b/src/drivers/ao_74hc497.c new file mode 100644 index 00000000..93c544c3 --- /dev/null +++ b/src/drivers/ao_74hc497.c @@ -0,0 +1,40 @@ +/* + * Copyright © 2012 Keith Packard + * + * 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; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +/* + * 74HC597 driver. + * Reads a single byte from the shift register + */ + +#include +#include + +uint8_t +ao_74hc497_read(void) +{ + static __xdata state; + ao_spi_get_bit(AO_74HC497_CS_PORT, AO_74HC497_CS_PIN, AO_74HC497_CS, AO_74HC497_SPI_BUS, AO_SPI_SPEED_FAST); + ao_spi_send(&state, 1, AO_74HC497_SPI_BUS); + ao_spi_put_bit(AO_74HC497_CS_PORT, AO_74HC497_CS_PIN, AO_74HC497_CS, AO_74HC497_SPI_BUS); + return state; +} + +void +ao_74hc497_init(void) +{ + ao_enable_output(AO_74HC497_CS_PORT, AO_74HC497_CS_PIN, AO_74HC497_CS, 1); +} diff --git a/src/drivers/ao_74hc497.h b/src/drivers/ao_74hc497.h new file mode 100644 index 00000000..6df7bcae --- /dev/null +++ b/src/drivers/ao_74hc497.h @@ -0,0 +1,27 @@ +/* + * Copyright © 2012 Keith Packard + * + * 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; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#ifndef _AO_74HC497_H_ +#define _AO_74HC497_H_ + +uint8_t +ao_74hc497_read(void); + +void +ao_74hc497_init(void); + +#endif /* _AO_74HC497_H_ */ diff --git a/src/drivers/ao_pad.c b/src/drivers/ao_pad.c new file mode 100644 index 00000000..21aa788d --- /dev/null +++ b/src/drivers/ao_pad.c @@ -0,0 +1,227 @@ +/* + * Copyright © 2012 Keith Packard + * + * 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; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#include +#include +#include + +__xdata uint8_t ao_pad_ignite; + +#define ao_pad_igniter_status(c) AO_PAD_IGNITER_STATUS_UNKNOWN +#define ao_pad_arm_status() AO_PAD_ARM_STATUS_UNKNOWN + +#if 0 +#define PRINTD(...) printf(__VA_ARGS__) +#else +#define PRINTD(...) +#endif + +static void +ao_pad_run(void) +{ + for (;;) { + while (!ao_pad_ignite) + ao_sleep(&ao_pad_ignite); + /* + * Actually set the pad bits + */ + AO_PAD_PORT = (AO_PAD_PORT & (~AO_PAD_ALL_PINS)) | ao_pad_ignite; + while (ao_pad_ignite) { + ao_pad_ignite = 0; + ao_delay(AO_PAD_FIRE_TIME); + } + AO_PAD_PORT &= ~(AO_PAD_ALL_PINS); + } +} + +static void +ao_pad_status(void) +{ + for (;;) { + ao_delay(AO_SEC_TO_TICKS(1)); +#if 0 + if (ao_igniter_status(ao_igniter_drogue) == ao_igniter_ready) { + if (ao_igniter_status(ao_igniter_main) == ao_igniter_ready) { + for (i = 0; i < 5; i++) { + ao_beep_for(AO_BEEP_MID, AO_MS_TO_TICKS(50)); + ao_delay(AO_MS_TO_TICKS(100)); + } + } else { + ao_beep_for(AO_BEEP_MID, AO_MS_TO_TICKS(200)); + } + } +#endif + } +} + +static __pdata uint8_t ao_pad_armed; +static __pdata uint16_t ao_pad_arm_time; +static __pdata uint8_t ao_pad_box; + +static void +ao_pad(void) +{ + static __xdata struct ao_pad_command command; + static __xdata struct ao_pad_query query; + int16_t time_difference; + uint8_t c; + + ao_led_off(AO_LED_RED); + ao_beep_for(AO_BEEP_MID, AO_MS_TO_TICKS(200)); + ao_pad_box = ao_74hc497_read(); + for (;;) { + flush(); + if (ao_radio_cmac_recv(&command, sizeof (command), 0) != AO_RADIO_CMAC_OK) + continue; + + PRINTD ("tick %d serial %d cmd %d channel %d\n", + command.tick, command.serial, command.cmd, command.channel); + + switch (command.cmd) { + case AO_LAUNCH_ARM: + if (command.box != ao_pad_box) { + PRINTD ("box number mismatch\n"); + break; + } + + if (command.channels & ~(AO_PAD_ALL_PINS)) + break; + + time_difference = command.tick - ao_time(); + PRINTD ("arm tick %d local tick %d\n", command.tick, ao_time()); + if (time_difference < 0) + time_difference = -time_difference; + if (time_difference > 10) { + PRINTD ("time difference too large %d\n", time_difference); + break; + } + PRINTD ("armed\n"); + ao_pad_armed = command.channels; + ao_pad_arm_time = ao_time(); + + /* fall through ... */ + + case AO_LAUNCH_QUERY: + if (command.box != ao_pad_box) { + PRINTD ("box number mismatch\n"); + break; + } + + query.tick = ao_time(); + query.box = ao_pad_box; + query.channels = AO_PAD_ALL_PINS; + query.armed = ao_pad_armed; + query.arm_status = ao_pad_arm_status(); + for (c = 0; c < AO_PAD_NUM; c++) + query.igniter_status[c] = ao_pad_igniter_status(c); + PRINTD ("query tick %d serial %d channel %d valid %d arm %d igniter %d\n", + query.tick, query.serial, query.channel, query.valid, query.arm_status, + query.igniter_status); + ao_radio_cmac_send(&query, sizeof (query)); + break; + case AO_LAUNCH_FIRE: + if (!ao_pad_armed) { + PRINTD ("not armed\n"); + break; + } + if ((uint16_t) (ao_time() - ao_pad_arm_time) > AO_SEC_TO_TICKS(20)) { + PRINTD ("late pad arm_time %d time %d\n", + ao_pad_arm_time, ao_time()); + break; + } + time_difference = command.tick - ao_time(); + if (time_difference < 0) + time_difference = -time_difference; + if (time_difference > 10) { + PRINTD ("time different too large %d\n", time_difference); + break; + } + PRINTD ("ignite\n"); + ao_pad_ignite = ao_pad_armed; + ao_wakeup(&ao_pad_ignite); + break; + } + } +} + +void +ao_pad_test(void) +{ +#if 0 + switch (ao_igniter_status(ao_igniter_drogue)) { + case ao_igniter_ready: + case ao_igniter_active: + printf ("Armed: "); + switch (ao_igniter_status(ao_igniter_main)) { + default: + printf("unknown status\n"); + break; + case ao_igniter_ready: + printf("igniter good\n"); + break; + case ao_igniter_open: + printf("igniter bad\n"); + break; + } + break; + default: + printf("Disarmed\n"); + } +#endif +} + +void +ao_pad_manual(void) +{ + ao_cmd_white(); + if (!ao_match_word("DoIt")) + return; + ao_cmd_white(); + ao_pad_ignite = 1; + ao_wakeup(&ao_pad_ignite); +} + +static __xdata struct ao_task ao_pad_task; +static __xdata struct ao_task ao_pad_ignite_task; +static __xdata struct ao_task ao_pad_status_task; + +__code struct ao_cmds ao_pad_cmds[] = { + { ao_pad_test, "t\0Test pad continuity" }, + { ao_pad_manual, "i \0Fire igniter. is doit with D&I" }, + { 0, NULL } +}; + +void +ao_pad_init(void) +{ +#if AO_PAD_NUM > 0 + ao_enable_output(AO_PAD_PORT, AO_PAD_PIN_0, AO_PAD_0, 0); +#endif +#if AO_PAD_NUM > 1 + ao_enable_output(AO_PAD_PORT, AO_PAD_PIN_1, AO_PAD_1, 0); +#endif +#if AO_PAD_NUM > 2 + ao_enable_output(AO_PAD_PORT, AO_PAD_PIN_2, AO_PAD_2, 0); +#endif +#if AO_PAD_NUM > 3 + ao_enable_output(AO_PAD_PORT, AO_PAD_PIN_3, AO_PAD_3, 0); +#endif + ao_cmd_register(&ao_pad_cmds[0]); + ao_add_task(&ao_pad_task, ao_pad, "pad listener"); + ao_add_task(&ao_pad_ignite_task, ao_pad_run, "pad igniter"); + ao_add_task(&ao_pad_status_task, ao_pad_status, "pad status"); +} diff --git a/src/drivers/ao_pad.h b/src/drivers/ao_pad.h new file mode 100644 index 00000000..9ea016ff --- /dev/null +++ b/src/drivers/ao_pad.h @@ -0,0 +1,67 @@ +/* + * Copyright © 2012 Keith Packard + * + * 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; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#ifndef _AO_PAD_H_ +#define _AO_PAD_H_ + +#define AO_PAD_MAX_CHANNELS 8 + +struct ao_pad_command { + uint16_t tick; + uint16_t box; + uint8_t cmd; + uint8_t channels; +}; + +/* Report current telefire status. + */ + +#define AO_PAD_QUERY 1 + +struct ao_pad_query { + uint16_t tick; /* telefire tick */ + uint16_t box; /* telefire box number */ + uint8_t channels; /* which chanels are present */ + uint8_t armed; /* which channels are armed */ + uint8_t arm_status; /* status of arming switch */ + uint8_t igniter_status[AO_PAD_MAX_CHANNELS]; /* status for each igniter */ +}; + +/* Set current armed pads, report back status + */ + +#define AO_PAD_ARM 2 + +/* Fire current armed pads for 200ms, no report + */ +#define AO_PAD_FIRE 3 + +#define AO_PAD_FIRE_TIME AO_MS_TO_TICKS(200) + +#define AO_PAD_ARM_STATUS_DISARMED 0 +#define AO_PAD_ARM_STATUS_ARMED 1 +#define AO_PAD_ARM_STATUS_UNKNOWN 2 + +#define AO_PAD_IGNITER_STATUS_NO_IGNITER_RELAY_OPEN 0 +#define AO_PAD_IGNITER_STATUS_GOOD_IGNITER_RELAY_OPEN 1 +#define AO_PAD_IGNITER_STATUS_NO_IGNITER_RELAY_CLOSED 2 +#define AO_PAD_IGNITER_STATUS_UNKNOWN 3 + +void +ao_pad_init(void); + +#endif /* _AO_PAD_H_ */ diff --git a/src/drivers/ao_pca9922.c b/src/drivers/ao_pca9922.c new file mode 100644 index 00000000..dc006f55 --- /dev/null +++ b/src/drivers/ao_pca9922.c @@ -0,0 +1,78 @@ +/* + * Copyright © 2012 Keith Packard + * + * 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; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +/* + * PCA9922 LED driver. This uses SPI to send a single byte to the device to + * set the current state of the LEDs using the existing LED interface + */ + +#include + +static __xdata uint8_t ao_led_state; + +static void +ao_led_apply(void) +{ + /* Don't try the SPI bus during initialization */ + if (!ao_cur_task) + return; + ao_spi_get_bit(AO_PCA9922_CS_PORT, AO_PCA9922_CS_PIN, AO_PCA9922_CS, AO_PCA9922_SPI_BUS, AO_SPI_SPEED_FAST); + ao_spi_send(&ao_led_state, 1, AO_PCA9922_SPI_BUS); + ao_spi_put_bit(AO_PCA9922_CS_PORT, AO_PCA9922_CS_PIN, AO_PCA9922_CS, AO_PCA9922_SPI_BUS); +} + +void +ao_led_on(uint8_t colors) +{ + ao_led_state |= colors; + ao_led_apply(); +} + +void +ao_led_off(uint8_t colors) +{ + ao_led_state &= ~colors; + ao_led_apply(); +} + +void +ao_led_set(uint8_t colors) +{ + ao_led_state = colors; + ao_led_apply(); +} + +void +ao_led_toggle(uint8_t colors) +{ + ao_led_state ^= colors; + ao_led_apply(); +} + +void +ao_led_for(uint8_t colors, uint16_t ticks) __reentrant +{ + ao_led_on(colors); + ao_delay(ticks); + ao_led_off(colors); +} + +void +ao_led_init(uint8_t enable) +{ + ao_enable_output(AO_PCA9922_CS_PORT, AO_PCA9922_CS_PIN, AO_PCA9922_CS, 1); +} diff --git a/src/telefire-v0.1/Makefile b/src/telefire-v0.1/Makefile new file mode 100644 index 00000000..09cb88fb --- /dev/null +++ b/src/telefire-v0.1/Makefile @@ -0,0 +1,101 @@ +# +# TeleFire build file +# + +TELEFIRE_VER=0.1 +TELEFIRE_DEF=0_1 + +vpath %.c ..:../core:../cc1111:../drivers:../product +vpath %.h ..:../core:../cc1111:../drivers:../product +vpath ao-make-product.5c ../util + +ifndef VERSION +include ../Version +endif + +INC = \ + ao.h \ + ao_pins.h \ + ao_arch.h \ + ao_arch_funcs.h \ + cc1111.h \ + ao_product.h + +CORE_SRC = \ + ao_cmd.c \ + ao_config.c \ + ao_convert.c \ + ao_mutex.c \ + ao_panic.c \ + ao_stdio.c \ + ao_storage.c \ + ao_task.c \ + ao_freq.c + +CC1111_SRC = \ + ao_adc.c \ + ao_aes.c \ + ao_beep.c \ + ao_dma.c \ + ao_intflash.c \ + ao_radio.c \ + ao_radio_cmac.c \ + ao_romconfig.c \ + ao_serial.c \ + ao_spi.c \ + ao_string.c \ + ao_timer.c \ + ao_usb.c \ + _bp.c + +DRIVER_SRC = \ + ao_pca9922.c \ + ao_74hc497.c \ + ao_pad.c + +PRODUCT_SRC = \ + ao_telefire.c + +SRC = \ + $(CORE_SRC) \ + $(CC1111_SRC) \ + $(DRIVER_SRC) \ + $(PRODUCT_SRC) + +PROGNAME = telefire-v$(TELEFIRE_VER) +PROG = $(PROGNAME)-$(VERSION).ihx +PRODUCT=TeleFire-v$(TELEFIRE_VER) +PRODUCT_DEF=-DTELEFIRE_V_$(TELEFIRE_DEF) +IDPRODUCT=0x000f +CODESIZE=0x6700 + +include ../cc1111/Makefile.cc1111 + +NICKLE=nickle +CHECK_STACK=sh ../util/check-stack + +V=0 +# The user has explicitly enabled quiet compilation. +ifeq ($(V),0) +quiet = @printf " $1 $2 $@\n"; $($1) +endif +# Otherwise, print the full command line. +quiet ?= $($1) + +all: ../$(PROG) + +../$(PROG): $(REL) Makefile + $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(REL) && cp $(PROG) $(PMAP) .. + $(call quiet,CHECK_STACK) ../cc1111/ao_arch.h $(PMEM) || rm $@ + +ao_product.h: ao-make-product.5c ../Version + $(call quiet,NICKLE,$<) $< -m altusmetrum.org -i $(IDPRODUCT) -p $(PRODUCT) -v $(VERSION) > $@ + +distclean: clean + +clean: clean-cc1111 + +install: + +uninstall: + diff --git a/src/telefire-v0.1/ao_pins.h b/src/telefire-v0.1/ao_pins.h new file mode 100644 index 00000000..4cf523fc --- /dev/null +++ b/src/telefire-v0.1/ao_pins.h @@ -0,0 +1,94 @@ +/* + * Copyright © 2010 Keith Packard + * + * 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; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#ifndef _AO_PINS_H_ +#define _AO_PINS_H_ + +#define HAS_RADIO 1 + +#define HAS_FLIGHT 0 +#define HAS_USB 1 +#define HAS_BEEP 1 +#define HAS_GPS 0 +#define HAS_SERIAL_1 0 +#define HAS_ADC 1 +#define HAS_DBG 0 +#define HAS_EEPROM 1 +#define HAS_LOG 0 +#define USE_INTERNAL_FLASH 1 +#define DBG_ON_P1 0 +#define IGNITE_ON_P2 0 +#define IGNITE_ON_P1 1 +#define IGNITE_ON_P0 0 +#define PACKET_HAS_MASTER 0 +#define PACKET_HAS_SLAVE 0 +#define AO_LED_RED 2 +#define AO_LED_GREEN 1 +#define LEDS_AVAILABLE (0xff) +#define HAS_EXTERNAL_TEMP 0 +#define HAS_ACCEL_REF 0 +#define SPI_CS_ON_P1 1 +#define HAS_AES 1 + +#define SPI_CS_PORT P1 +#define SPI_CS_SEL P1SEL +#define SPI_CS_DIR P1DIR + +#define AO_74HC497_CS_PORT P1 +#define AO_74HC497_CS_PIN 4 +#define AO_74HC497_CS P1_4 + +#define AO_PCA9922_CS_PORT P1 +#define AO_PCA9922_CS_PIN 4 +#define AO_PCA9922_CS P1_4 + +#define AO_PAD_NUM 4 +#define AO_PAD_PORT P1 +#define AO_PAD_DIR P1DIR +#define AO_PAD_PIN_0 0 +#define AO_PAD_0 P1_0 +#define AO_PAD_PIN_1 1 +#define AO_PAD_1 P1_1 +#define AO_PAD_PIN_2 2 +#define AO_PAD_2 P1_2 +#define AO_PAD_PIN_3 3 +#define AO_PAD_3 P1_3 +#define AO_PAD_ALL_PINS ((1 << AO_PAD_PIN_0) | (1 << AO_PAD_PIN_1) | (1 << AO_PAD_PIN_2) | (1 << AO_PAD_PIN_3)) + +/* test these values with real igniters */ +#define AO_PAD_RELAY_CLOSED 3524 +#define AO_PAD_NO_IGNITER 16904 +#define AO_PAD_GOOD_IGNITER 22514 + +struct ao_adc { + int16_t sense[4]; + int16_t pyro; + int16_t batt; +}; + +#define AO_ADC_DUMP(p) \ + printf ("tick: %5u 0: %5d 1: %5d 2: %5d 3: %5d pyro: %5d batt %5d\n", \ + (p)->adc.sense[0], \ + (p)->adc.sense[1], \ + (p)->adc.sense[2], \ + (p)->adc.sense[3], \ + (p)->adc.pyro, \ + (p)->adc.batt) + +#define AO_ADC_PINS ((1 << 0) | (1 << 1) | (1 << 2) | (1 << 3) | (1 << 4) | (1 << 5)) + +#endif /* _AO_PINS_H_ */ diff --git a/src/telefire-v0.1/ao_telefire.c b/src/telefire-v0.1/ao_telefire.c new file mode 100644 index 00000000..96413a63 --- /dev/null +++ b/src/telefire-v0.1/ao_telefire.c @@ -0,0 +1,41 @@ +/* + * Copyright © 2012 Keith Packard + * + * 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; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#include "ao.h" +#include "ao_pins.h" + +void +main(void) +{ + ao_clock_init(); + + ao_led_init(LEDS_AVAILABLE); + + ao_timer_init(); + ao_adc_init(); + ao_beep_init(); + ao_cmd_init(); + ao_spi_init(); + ao_storage_init(); + ao_usb_init(); + ao_radio_init(); + ao_aes_init(); + ao_radio_cmac_init(); + ao_pad_init(); + ao_config_init(); + ao_start_scheduler(); +} -- cgit v1.2.3 From 2e7e304e67bc1e094282c8668fa8cccf09f9c9b4 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 29 Jul 2012 19:48:08 -0700 Subject: altos: Add driver for STM internal flash Signed-off-by: Keith Packard --- src/stm/ao_eeprom_stm.c | 191 ++++++++++++++++++++++++++++++++++++++++++++++++ src/stm/stm32l.h | 24 ++++++ 2 files changed, 215 insertions(+) create mode 100644 src/stm/ao_eeprom_stm.c (limited to 'src') diff --git a/src/stm/ao_eeprom_stm.c b/src/stm/ao_eeprom_stm.c new file mode 100644 index 00000000..1e51b417 --- /dev/null +++ b/src/stm/ao_eeprom_stm.c @@ -0,0 +1,191 @@ +/* + * Copyright © 2012 Keith Packard + * + * 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; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#include +#include + +/* Total bytes of available storage */ +ao_pos_t ao_storage_total = 4096; + +/* Block size - device is erased in these units. */ +ao_pos_t ao_storage_block = 1024; + +/* Byte offset of config block. Will be ao_storage_block bytes long */ +ao_pos_t ao_storage_config = 0; + +/* Storage unit size - device reads and writes must be within blocks of this size. */ +uint16_t ao_storage_unit = 1024; + +/* Location of eeprom in address space */ +#define stm_eeprom ((uint8_t *) 0x08080000) + +/* + * The internal flash chip is arranged in 8 byte sectors; the + * chip cannot erase in units smaller than that. + * + * Writing happens in units of 2 bytes and + * can only change bits from 1 to 0. So, you can rewrite + * the same contents, or append to an existing page easily enough + */ + +/* + * Erase the specified sector + */ +uint8_t +ao_storage_erase(ao_pos_t pos) __reentrant +{ + /* Not necessary */ + return 1; +} + +static void +ao_intflash_unlock(void) +{ + /* Unlock Data EEPROM and FLASH_PECR register */ + stm_flash.pekeyr = STM_FLASH_PEKEYR_PEKEY1; + stm_flash.pekeyr = STM_FLASH_PEKEYR_PEKEY2; + + /* Configure the FTDW bit (FLASH_PECR[8]) to execute + * word write, whatever the previous value of the word + * being written to + */ + stm_flash.pecr = ((0 << STM_FLASH_PECR_OBL_LAUNCH) | + (0 << STM_FLASH_PECR_ERRIE) | + (0 << STM_FLASH_PECR_EOPIE) | + (0 << STM_FLASH_PECR_FPRG) | + (0 << STM_FLASH_PECR_ERASE) | + (0 << STM_FLASH_PECR_FTDW) | + (1 << STM_FLASH_PECR_DATA) | + (0 << STM_FLASH_PECR_PROG) | + (0 << STM_FLASH_PECR_OPTLOCK) | + (0 << STM_FLASH_PECR_PRGLOCK) | + (0 << STM_FLASH_PECR_PELOCK)); +} + +static void +ao_intflash_lock(void) +{ + stm_flash.pecr |= (1 << STM_FLASH_PECR_PELOCK); +} + +static void +ao_intflash_write32(uint16_t pos, uint32_t w) +{ + uint32_t *addr; + + addr = (uint32_t *) (stm_eeprom + pos); + + /* Write a word to a valid address in the data EEPROM */ + *addr = w; + + /* Wait for the flash unit to go idle */ + while (stm_flash.sr & (1 << STM_FLASH_SR_BSY)) + ; +} + +static void +ao_intflash_write8(uint16_t pos, uint8_t d) +{ + uint32_t w, *addr, mask; + uint8_t shift; + + addr = (uint32_t *) (stm_eeprom + (pos & ~3)); + + /* Compute word to be written */ + shift = (pos & 3) << 3; + mask = 0xff << shift; + w = (*addr & ~mask) | (d << shift); + + ao_intflash_write32(pos & ~3, w); +} + +static uint8_t +ao_intflash_read(uint16_t pos) +{ + return stm_eeprom[pos]; +} + +/* + * Write to flash + */ + +uint8_t +ao_storage_device_write(ao_pos_t pos32, __xdata void *v, uint16_t len) __reentrant +{ + uint16_t pos = pos32; + __xdata uint8_t *d = v; + + if (pos >= ao_storage_total || pos + len > ao_storage_total) + return 0; + + ao_intflash_unlock(); + while (len) { + if ((pos & 3) == 0 && len >= 4) { + uint32_t w; + + w = d[0] | (d[1] << 8) | (d[2] << 16) | (d[3] << 24); + ao_intflash_write32(pos, w); + pos += 4; + d += 4; + len -= 4; + } else { + ao_intflash_write8(pos, *d); + pos += 1; + d += 1; + len -= 1; + } + } + ao_intflash_lock(); + + return 1; +} + +/* + * Read from flash + */ +uint8_t +ao_storage_device_read(ao_pos_t pos, __xdata void *v, uint16_t len) __reentrant +{ + uint8_t *d = v; + + if (pos >= ao_storage_total || pos + len > ao_storage_total) + return 0; + while (len--) + *d++ = ao_intflash_read(pos++); + return 1; +} + +void +ao_storage_flush(void) __reentrant +{ +} + +void +ao_storage_setup(void) +{ +} + +void +ao_storage_device_info(void) __reentrant +{ + printf ("Using internal flash\n"); +} + +void +ao_storage_device_init(void) +{ +} diff --git a/src/stm/stm32l.h b/src/stm/stm32l.h index ff8dddff..4d665e8b 100644 --- a/src/stm/stm32l.h +++ b/src/stm/stm32l.h @@ -281,6 +281,30 @@ extern struct stm_flash stm_flash; #define STM_FLASH_ACR_PRFEN (1) #define STM_FLASH_ACR_LATENCY (0) +#define STM_FLASH_PECR_OBL_LAUNCH 18 +#define STM_FLASH_PECR_ERRIE 17 +#define STM_FLASH_PECR_EOPIE 16 +#define STM_FLASH_PECR_FPRG 10 +#define STM_FLASH_PECR_ERASE 9 +#define STM_FLASH_PECR_FTDW 8 +#define STM_FLASH_PECR_DATA 4 +#define STM_FLASH_PECR_PROG 3 +#define STM_FLASH_PECR_OPTLOCK 2 +#define STM_FLASH_PECR_PRGLOCK 1 +#define STM_FLASH_PECR_PELOCK 0 + +#define STM_FLASH_SR_OPTVERR 11 +#define STM_FLASH_SR_SIZERR 10 +#define STM_FLASH_SR_PGAERR 9 +#define STM_FLASH_SR_WRPERR 8 +#define STM_FLASH_SR_READY 3 +#define STM_FLASH_SR_ENDHV 2 +#define STM_FLASH_SR_EOP 1 +#define STM_FLASH_SR_BSY 0 + +#define STM_FLASH_PEKEYR_PEKEY1 0x89ABCDEF +#define STM_FLASH_PEKEYR_PEKEY2 0x02030405 + struct stm_rcc { vuint32_t cr; vuint32_t icscr; -- cgit v1.2.3 From 2610b316eb939c1532061646b05207fcd54d984f Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 5 Aug 2012 12:15:36 -0700 Subject: src/cc1111: Add ao_gpio_set macro Allows general GPIO-using code to run on cc1111 Signed-off-by: Keith Packard --- src/cc1111/ao_arch_funcs.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/cc1111/ao_arch_funcs.h b/src/cc1111/ao_arch_funcs.h index 0737e7ab..29755b5c 100644 --- a/src/cc1111/ao_arch_funcs.h +++ b/src/cc1111/ao_arch_funcs.h @@ -88,3 +88,4 @@ ao_spi_init(void); #define token_paster(x,y) x ## y #define token_evaluator(x,y) token_paster(x,y) #define ao_enable_output(port,bit,pin,v) cc1111_enable_output(port,token_evaluator(port,DIR), token_evaluator(port,SEL), pin, bit, v) +#define ao_gpio_set(port, bit, pin, v) ((pin) = (v)) -- cgit v1.2.3 From 39594fdb3e30a1a25dd894c217e3d9d773bab972 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 5 Aug 2012 12:16:25 -0700 Subject: src/cc1111: Allow serial0 without serial1 The ao_serial_speed structure is needed by serial0 too. Signed-off-by: Keith Packard --- src/cc1111/ao_serial.c | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/cc1111/ao_serial.c b/src/cc1111/ao_serial.c index d90103b0..d5431070 100644 --- a/src/cc1111/ao_serial.c +++ b/src/cc1111/ao_serial.c @@ -17,6 +17,25 @@ #include "ao.h" +const __code struct ao_serial_speed ao_serial_speeds[] = { + /* [AO_SERIAL_SPEED_4800] = */ { + /* .baud = */ 163, + /* .gcr = */ (7 << UxGCR_BAUD_E_SHIFT) | UxGCR_ORDER_LSB + }, + /* [AO_SERIAL_SPEED_9600] = */ { + /* .baud = */ 163, + /* .gcr = */ (8 << UxGCR_BAUD_E_SHIFT) | UxGCR_ORDER_LSB + }, + /* [AO_SERIAL_SPEED_19200] = */ { + /* .baud = */ 163, + /* .gcr = */ (9 << UxGCR_BAUD_E_SHIFT) | UxGCR_ORDER_LSB + }, + /* [AO_SERIAL_SPEED_57600] = */ { + /* .baud = */ 59, + /* .gcr = */ (11 << UxGCR_BAUD_E_SHIFT) | UxGCR_ORDER_LSB + }, +}; + #if HAS_SERIAL_0 volatile __xdata struct ao_fifo ao_serial0_rx_fifo; @@ -181,25 +200,6 @@ ao_serial1_drain(void) __critical ao_sleep(&ao_serial1_tx_fifo); } -const __code struct ao_serial_speed ao_serial_speeds[] = { - /* [AO_SERIAL_SPEED_4800] = */ { - /* .baud = */ 163, - /* .gcr = */ (7 << UxGCR_BAUD_E_SHIFT) | UxGCR_ORDER_LSB - }, - /* [AO_SERIAL_SPEED_9600] = */ { - /* .baud = */ 163, - /* .gcr = */ (8 << UxGCR_BAUD_E_SHIFT) | UxGCR_ORDER_LSB - }, - /* [AO_SERIAL_SPEED_19200] = */ { - /* .baud = */ 163, - /* .gcr = */ (9 << UxGCR_BAUD_E_SHIFT) | UxGCR_ORDER_LSB - }, - /* [AO_SERIAL_SPEED_57600] = */ { - /* .baud = */ 59, - /* .gcr = */ (11 << UxGCR_BAUD_E_SHIFT) | UxGCR_ORDER_LSB - }, -}; - void ao_serial1_set_speed(uint8_t speed) { -- cgit v1.2.3 From 0f82021186565fda10df7893b95deae4a1f32778 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 5 Aug 2012 12:17:25 -0700 Subject: src/cc1111: Enable SPI slave mode This is untested... Signed-off-by: Keith Packard --- src/cc1111/ao_spi.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/cc1111/ao_spi.c b/src/cc1111/ao_spi.c index 1bf5e155..88cff9dd 100644 --- a/src/cc1111/ao_spi.c +++ b/src/cc1111/ao_spi.c @@ -40,6 +40,7 @@ static __xdata uint8_t ao_spi_const; void ao_spi_send_bus(void __xdata *block, uint16_t len) __reentrant { +#if !AO_SPI_SLAVE ao_dma_set_transfer(ao_spi_dma_in_id, &U0DBUFXADDR, &ao_spi_const, @@ -50,7 +51,7 @@ ao_spi_send_bus(void __xdata *block, uint16_t len) __reentrant DMA_CFG1_SRCINC_0 | DMA_CFG1_DESTINC_0 | DMA_CFG1_PRIORITY_NORMAL); - +#endif ao_dma_set_transfer(ao_spi_dma_out_id, block, &U0DBUFXADDR, @@ -62,11 +63,18 @@ ao_spi_send_bus(void __xdata *block, uint16_t len) __reentrant DMA_CFG1_DESTINC_0 | DMA_CFG1_PRIORITY_NORMAL); +#if !AO_SPI_SLAVE ao_dma_start(ao_spi_dma_in_id); +#endif ao_dma_start(ao_spi_dma_out_id); ao_dma_trigger(ao_spi_dma_out_id); +#if AO_SPI_SLAVE + __critical while (!ao_spi_dma_out_done) + ao_sleep(&ao_spi_dma_out_done); +#else __critical while (!ao_spi_dma_in_done) ao_sleep(&ao_spi_dma_in_done); +#endif } /* Receive bytes over SPI. @@ -115,10 +123,19 @@ ao_spi_recv_bus(void __xdata *block, uint16_t len) __reentrant * MO P1_5 * MI P1_4 * CLK P1_3 + * CSS P1_2 * - * Chip select is the responsibility of the caller + * Chip select is the responsibility of the caller in master mode */ +#if AO_SPI_SLAVE +#define CSS (1 << 2) +#define UxCSR_DIRECTION UxCSR_SLAVE +#else +#define CSS 0 +#define UxCSR_DIRECTION UxCSR_MASTER +#endif + void ao_spi_init(void) { @@ -131,7 +148,7 @@ ao_spi_init(void) P2SEL = (P2SEL & ~P2SEL_PRI3P1_MASK) | P2SEL_PRI3P1_USART0; /* Make the SPI pins be controlled by the USART peripheral */ - P1SEL |= ((1 << 5) | (1 << 4) | (1 << 3)); + P1SEL |= ((1 << 5) | (1 << 4) | (1 << 3) | CSS); /* Set up OUT DMA */ ao_spi_dma_out_id = ao_dma_alloc(&ao_spi_dma_out_done); @@ -143,7 +160,7 @@ ao_spi_init(void) * * SPI master mode */ - U0CSR = (UxCSR_MODE_SPI | UxCSR_RE | UxCSR_MASTER); + U0CSR = (UxCSR_MODE_SPI | UxCSR_RE | UxCSR_DIRECTION); /* Set the baud rate and signal parameters * -- cgit v1.2.3 From de701d5a234cd21930cf92c9cabebb0e230da9b5 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 5 Aug 2012 14:58:40 -0700 Subject: altos: Build ao_kalman.h from cc1111 subdirs as needed Signed-off-by: Keith Packard --- src/cc1111/Makefile.cc1111 | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/cc1111/Makefile.cc1111 b/src/cc1111/Makefile.cc1111 index bfd444dd..0e19603b 100644 --- a/src/cc1111/Makefile.cc1111 +++ b/src/cc1111/Makefile.cc1111 @@ -33,3 +33,6 @@ clean-cc1111: rm -f $(PROGNAME)-* rm -f ao_product.h rm -f ../$(PROGNAME)-* + +../ao_kalman.h: + +(cd .. && make ao_kalman.h) -- cgit v1.2.3 From 6171892fa32e8a662a494ec6ba28a82fddc68589 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 6 Aug 2012 19:33:44 -0700 Subject: altos: Add ao_gpio_get and ao_exti_set_mode Needed to support general GPIO interrupts Signed-off-by: Keith Packard --- src/stm/ao_arch_funcs.h | 13 +++++++++++++ src/stm/ao_exti.h | 3 +++ src/stm/ao_exti_stm.c | 14 ++++++++++++++ src/stm/stm32l.h | 2 +- 4 files changed, 31 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/stm/ao_arch_funcs.h b/src/stm/ao_arch_funcs.h index d2c973f5..3d8ca1f2 100644 --- a/src/stm/ao_arch_funcs.h +++ b/src/stm/ao_arch_funcs.h @@ -78,12 +78,25 @@ ao_spi_init(void); #define ao_gpio_set(port, bit, pin, v) stm_gpio_set(port, bit, v) +#define ao_gpio_get(port, bit, pin) stm_gpio_get(port, bit) + #define ao_enable_output(port,bit,pin,v) do { \ ao_enable_port(port); \ ao_gpio_set(port, bit, pin, v); \ stm_moder_set(port, bit, STM_MODER_OUTPUT);\ } while (0) +#define ao_enable_input(port,bit,mode) do { \ + ao_enable_port(port); \ + stm_moder_set(port, bit, STM_MODER_INPUT); \ + if (mode == AO_EXTI_MODE_PULL_UP) \ + stm_pupdr_set(port, bit, STM_PUPDR_PULL_UP); \ + else if (mode == AO_EXTI_MODE_PULL_DOWN) \ + stm_pupdr_set(port, bit, STM_PUPDR_PULL_DOWN); \ + else \ + stm_pupdr_set(port, bit, STM_PUPDR_NONE); \ + } while (0) + #define ao_enable_cs(port,bit) do { \ stm_gpio_set((port), bit, 1); \ stm_moder_set((port), bit, STM_MODER_OUTPUT); \ diff --git a/src/stm/ao_exti.h b/src/stm/ao_exti.h index b579ad9f..35b56b57 100644 --- a/src/stm/ao_exti.h +++ b/src/stm/ao_exti.h @@ -29,6 +29,9 @@ void ao_exti_setup(struct stm_gpio *gpio, uint8_t pin, uint8_t mode, void (*callback)()); +void +ao_exti_set_mode(struct stm_gpio *gpio, uint8_t pin, uint8_t mode); + void ao_exti_set_callback(struct stm_gpio *gpio, uint8_t pin, void (*callback)()); diff --git a/src/stm/ao_exti_stm.c b/src/stm/ao_exti_stm.c index d54e6ee6..11099b02 100644 --- a/src/stm/ao_exti_stm.c +++ b/src/stm/ao_exti_stm.c @@ -115,6 +115,20 @@ ao_exti_setup (struct stm_gpio *gpio, uint8_t pin, uint8_t mode, void (*callback stm_nvic_set_enable(irq); } +void +ao_exti_set_mode(struct stm_gpio *gpio, uint8_t pin, uint8_t mode) { + uint32_t mask = 1 << pin; + + if (mode & AO_EXTI_MODE_RISING) + stm_exti.rtsr |= mask; + else + stm_exti.rtsr &= ~mask; + if (mode & AO_EXTI_MODE_FALLING) + stm_exti.ftsr |= mask; + else + stm_exti.ftsr &= ~mask; +} + void ao_exti_set_callback(struct stm_gpio *gpio, uint8_t pin, void (*callback)()) { ao_exti_callback[pin] = callback; diff --git a/src/stm/stm32l.h b/src/stm/stm32l.h index 4d665e8b..3a498a0a 100644 --- a/src/stm/stm32l.h +++ b/src/stm/stm32l.h @@ -167,7 +167,7 @@ stm_gpio_set(struct stm_gpio *gpio, int pin, uint8_t value) { } static inline uint8_t -stm_gpio_isset(struct stm_gpio *gpio, int pin) { +stm_gpio_get(struct stm_gpio *gpio, int pin) { return (gpio->idr >> pin) & 1; } -- cgit v1.2.3 From b0b52ca73bc836336ecc70247a9ed1dd633920d9 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 6 Aug 2012 19:34:34 -0700 Subject: altos: Add quadrature driver Signed-off-by: Keith Packard --- src/drivers/ao_quadrature.c | 108 ++++++++++++++++++++++++++++++++++++++++++++ src/drivers/ao_quadrature.h | 30 ++++++++++++ 2 files changed, 138 insertions(+) create mode 100644 src/drivers/ao_quadrature.c create mode 100644 src/drivers/ao_quadrature.h (limited to 'src') diff --git a/src/drivers/ao_quadrature.c b/src/drivers/ao_quadrature.c new file mode 100644 index 00000000..1cde32e7 --- /dev/null +++ b/src/drivers/ao_quadrature.c @@ -0,0 +1,108 @@ +/* + * Copyright © 2012 Keith Packard + * + * 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; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#include +#include +#include + +__xdata int32_t ao_quadrature_count; + +static uint8_t wait_clear; + +static void +ao_quadrature_isr(void) +{ + if (wait_clear) { + wait_clear = 0; + ao_exti_set_mode(AO_QUADRATURE_PORT, AO_QUADRATURE_A, AO_EXTI_MODE_RISING); + } else { + wait_clear = 1; + ao_exti_set_mode(AO_QUADRATURE_PORT, AO_QUADRATURE_A, AO_EXTI_MODE_FALLING); + if (ao_gpio_get(AO_QUADRATURE_PORT, AO_QUADRATURE_B, AO_QUADRATURE_B_PIN)) + ao_quadrature_count++; + else + ao_quadrature_count--; + ao_wakeup(&ao_quadrature_count); + } +} + +int32_t +ao_quadrature_poll(void) +{ + int32_t ret; + ao_arch_critical(ret = ao_quadrature_count;); + return ret; +} + +int32_t +ao_quadrature_wait(void) +{ + ao_sleep(&ao_quadrature_count); + return ao_quadrature_poll(); +} + +static void +ao_quadrature_test(void) +{ +#if 0 + for (;;) { + int32_t c; + printf ("waiting...\n"); + flush(); + c = ao_quadrature_wait(); + printf ("new count %d\n", c); + if (ao_stdin_ready) + break; + } +#endif + uint8_t a, old_a, b, old_b; + + old_a = 2; old_b = 2; + for (;;) { + a = ao_gpio_get(AO_QUADRATURE_PORT, AO_QUADRATURE_A, AO_QUADRATURE_A_PIN); + b = ao_gpio_get(AO_QUADRATURE_PORT, AO_QUADRATURE_B, AO_QUADRATURE_B_PIN); + if (a != old_a || b != old_b) { + printf ("A %d B %d\n", a, b); + flush(); + ao_yield(); + old_a = a; + old_b = b; + } + if (ao_stdin_ready) + break; + } + +} + +static const struct ao_cmds ao_quadrature_cmds[] = { + { ao_quadrature_test, "q\0Test quadrature" }, + { 0, NULL } +}; + +void +ao_quadrature_init(void) +{ + ao_quadrature_count = 0; + + ao_enable_port(AO_QUADRATURE_PORT); + ao_exti_setup(AO_QUADRATURE_PORT, AO_QUADRATURE_A, + AO_EXTI_MODE_PULL_UP|AO_EXTI_MODE_FALLING|AO_EXTI_PRIORITY_MED, + ao_quadrature_isr); + ao_exti_enable(AO_QUADRATURE_PORT, AO_QUADRATURE_A); + ao_enable_input(AO_QUADRATURE_PORT, AO_QUADRATURE_B, AO_EXTI_MODE_PULL_UP); + ao_cmd_register(&ao_quadrature_cmds[0]); +} diff --git a/src/drivers/ao_quadrature.h b/src/drivers/ao_quadrature.h new file mode 100644 index 00000000..7e1048bc --- /dev/null +++ b/src/drivers/ao_quadrature.h @@ -0,0 +1,30 @@ +/* + * Copyright © 2012 Keith Packard + * + * 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; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#ifndef _AO_QUADRATURE_H_ +#define _AO_QUADRATURE_H_ + +int32_t +ao_quadrature_wait(void); + +int32_t +ao_quadrature_poll(void); + +void +ao_quadrature_init(void); + +#endif /* _AO_QUADRATURE_H_ */ -- cgit v1.2.3 From ab379493dbe9923db8e458d2f4e0344df17d331c Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 6 Aug 2012 19:35:02 -0700 Subject: Signed-off-by: Keith Packard altos: Test quadrature driver --- src/stm-demo/Makefile | 4 +++- src/stm-demo/ao_demo.c | 4 ++++ src/stm-demo/ao_pins.h | 4 ++++ 3 files changed, 11 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/stm-demo/Makefile b/src/stm-demo/Makefile index 055a73af..52bb7b51 100644 --- a/src/stm-demo/Makefile +++ b/src/stm-demo/Makefile @@ -33,7 +33,9 @@ ALTOS_SRC = \ ao_spi_stm.c \ ao_adc_stm.c \ ao_i2c_stm.c \ - ao_usb_stm.c + ao_usb_stm.c \ + ao_exti_stm.c \ + ao_quadrature.c PRODUCT=StmDemo-v0.0 PRODUCT_DEF=-DSTM_DEMO diff --git a/src/stm-demo/ao_demo.c b/src/stm-demo/ao_demo.c index 9a581ff9..1b9813fe 100644 --- a/src/stm-demo/ao_demo.c +++ b/src/stm-demo/ao_demo.c @@ -16,6 +16,8 @@ */ #include "ao.h" +#include +#include struct ao_task demo_task; @@ -170,6 +172,8 @@ main(void) // ao_lcd_font_init(); ao_spi_init(); ao_i2c_init(); + ao_exti_init(); + ao_quadrature_init(); ao_timer_set_adc_interval(100); diff --git a/src/stm-demo/ao_pins.h b/src/stm-demo/ao_pins.h index 7e222122..17a76bd0 100644 --- a/src/stm-demo/ao_pins.h +++ b/src/stm-demo/ao_pins.h @@ -170,4 +170,8 @@ struct ao_adc { #define HAS_I2C_2 0 #define I2C_2_PB10_PB11 0 +#define AO_QUADRATURE_PORT &stm_gpioc +#define AO_QUADRATURE_A 0 +#define AO_QUADRATURE_B 1 + #endif /* _AO_PINS_H_ */ -- cgit v1.2.3 From 5f7e61c749b02ed16e368502062e39b0471e9257 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 6 Aug 2012 20:20:32 -0700 Subject: altos: Fix up quadrature driver Mostly works now, should work reliably with a bit of input filtering. Signed-off-by: Keith Packard --- src/drivers/ao_quadrature.c | 49 +++++++++++++++++++++++++++------------------ src/stm-demo/ao_pins.h | 4 ++-- 2 files changed, 31 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/drivers/ao_quadrature.c b/src/drivers/ao_quadrature.c index 1cde32e7..1f94aa44 100644 --- a/src/drivers/ao_quadrature.c +++ b/src/drivers/ao_quadrature.c @@ -21,23 +21,29 @@ __xdata int32_t ao_quadrature_count; -static uint8_t wait_clear; +static uint8_t ao_quadrature_state; + +#define BIT(a,b) ((a) | ((b) << 1)) +#define STATE(old_a, old_b, new_a, new_b) (((BIT(old_a, old_b) << 2) | BIT(new_a, new_b))) static void ao_quadrature_isr(void) { - if (wait_clear) { - wait_clear = 0; - ao_exti_set_mode(AO_QUADRATURE_PORT, AO_QUADRATURE_A, AO_EXTI_MODE_RISING); - } else { - wait_clear = 1; - ao_exti_set_mode(AO_QUADRATURE_PORT, AO_QUADRATURE_A, AO_EXTI_MODE_FALLING); - if (ao_gpio_get(AO_QUADRATURE_PORT, AO_QUADRATURE_B, AO_QUADRATURE_B_PIN)) - ao_quadrature_count++; - else - ao_quadrature_count--; - ao_wakeup(&ao_quadrature_count); + ao_quadrature_state = ((ao_quadrature_state & 3) << 2); + ao_quadrature_state |= ao_gpio_get(AO_QUADRATURE_PORT, AO_QUADRATURE_A, AO_QUADRATURE_A_PIN); + ao_quadrature_state |= ao_gpio_get(AO_QUADRATURE_PORT, AO_QUADRATURE_B, AO_QUADRATURE_B_PIN) << 1; + + switch (ao_quadrature_state) { + case STATE(0, 1, 0, 0): + ao_quadrature_count++; + break; + case STATE(1, 0, 0, 0): + ao_quadrature_count--; + break; + default: + return; } + ao_wakeup(&ao_quadrature_count); } int32_t @@ -58,17 +64,17 @@ ao_quadrature_wait(void) static void ao_quadrature_test(void) { -#if 0 +#if 1 for (;;) { int32_t c; - printf ("waiting...\n"); flush(); c = ao_quadrature_wait(); - printf ("new count %d\n", c); - if (ao_stdin_ready) + printf ("new count %6d\n", c); + if (c == 100) break; } #endif +#if 0 uint8_t a, old_a, b, old_b; old_a = 2; old_b = 2; @@ -76,7 +82,7 @@ ao_quadrature_test(void) a = ao_gpio_get(AO_QUADRATURE_PORT, AO_QUADRATURE_A, AO_QUADRATURE_A_PIN); b = ao_gpio_get(AO_QUADRATURE_PORT, AO_QUADRATURE_B, AO_QUADRATURE_B_PIN); if (a != old_a || b != old_b) { - printf ("A %d B %d\n", a, b); + printf ("A %d B %d count %ld\n", a, b, ao_quadrature_count); flush(); ao_yield(); old_a = a; @@ -85,7 +91,7 @@ ao_quadrature_test(void) if (ao_stdin_ready) break; } - +#endif } static const struct ao_cmds ao_quadrature_cmds[] = { @@ -100,9 +106,12 @@ ao_quadrature_init(void) ao_enable_port(AO_QUADRATURE_PORT); ao_exti_setup(AO_QUADRATURE_PORT, AO_QUADRATURE_A, - AO_EXTI_MODE_PULL_UP|AO_EXTI_MODE_FALLING|AO_EXTI_PRIORITY_MED, + AO_EXTI_MODE_PULL_UP|AO_EXTI_MODE_FALLING|AO_EXTI_MODE_RISING|AO_EXTI_PRIORITY_MED, ao_quadrature_isr); ao_exti_enable(AO_QUADRATURE_PORT, AO_QUADRATURE_A); - ao_enable_input(AO_QUADRATURE_PORT, AO_QUADRATURE_B, AO_EXTI_MODE_PULL_UP); + ao_exti_setup(AO_QUADRATURE_PORT, AO_QUADRATURE_B, + AO_EXTI_MODE_PULL_UP|AO_EXTI_MODE_FALLING|AO_EXTI_MODE_RISING|AO_EXTI_PRIORITY_MED, + ao_quadrature_isr); + ao_exti_enable(AO_QUADRATURE_PORT, AO_QUADRATURE_B); ao_cmd_register(&ao_quadrature_cmds[0]); } diff --git a/src/stm-demo/ao_pins.h b/src/stm-demo/ao_pins.h index 17a76bd0..1f5ef4ff 100644 --- a/src/stm-demo/ao_pins.h +++ b/src/stm-demo/ao_pins.h @@ -171,7 +171,7 @@ struct ao_adc { #define I2C_2_PB10_PB11 0 #define AO_QUADRATURE_PORT &stm_gpioc -#define AO_QUADRATURE_A 0 -#define AO_QUADRATURE_B 1 +#define AO_QUADRATURE_A 1 +#define AO_QUADRATURE_B 0 #endif /* _AO_PINS_H_ */ -- cgit v1.2.3 From 11046bc89b3ce6386f1005fc8476b08f54d6f5fb Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 6 Aug 2012 21:54:58 -0700 Subject: altos: Support multiple quadrature encoders. Signed-off-by: Keith Packard --- src/drivers/ao_quadrature.c | 90 +++++++++++++++++++++++++++++---------------- src/drivers/ao_quadrature.h | 4 +- src/stm-demo/ao_pins.h | 13 +++++-- 3 files changed, 70 insertions(+), 37 deletions(-) (limited to 'src') diff --git a/src/drivers/ao_quadrature.c b/src/drivers/ao_quadrature.c index 1f94aa44..aed4999e 100644 --- a/src/drivers/ao_quadrature.c +++ b/src/drivers/ao_quadrature.c @@ -19,46 +19,63 @@ #include #include -__xdata int32_t ao_quadrature_count; +__xdata int32_t ao_quadrature_count[AO_QUADRATURE_COUNT]; -static uint8_t ao_quadrature_state; +static uint8_t ao_quadrature_state[AO_QUADRATURE_COUNT]; #define BIT(a,b) ((a) | ((b) << 1)) #define STATE(old_a, old_b, new_a, new_b) (((BIT(old_a, old_b) << 2) | BIT(new_a, new_b))) +#define port(q) AO_QUADRATURE_ ## q ## _PORT +#define bita(q) AO_QUADRATURE_ ## q ## _A +#define bitb(q) AO_QUADRATURE_ ## q ## _B + +#define ao_quadrature_update(q) do { \ + ao_quadrature_state[q] = ((ao_quadrature_state[q] & 3) << 2); \ + ao_quadrature_state[q] |= ao_gpio_get(port(q), bita(q), 0); \ + ao_quadrature_state[q] |= ao_gpio_get(port(q), bitb(q), 0) << 1; \ + } while (0) + + static void ao_quadrature_isr(void) { - ao_quadrature_state = ((ao_quadrature_state & 3) << 2); - ao_quadrature_state |= ao_gpio_get(AO_QUADRATURE_PORT, AO_QUADRATURE_A, AO_QUADRATURE_A_PIN); - ao_quadrature_state |= ao_gpio_get(AO_QUADRATURE_PORT, AO_QUADRATURE_B, AO_QUADRATURE_B_PIN) << 1; + uint8_t q; +#if AO_QUADRATURE_COUNT > 0 + ao_quadrature_update(0); +#endif +#if AO_QUADRATURE_COUNT > 1 + ao_quadrature_update(1); +#endif - switch (ao_quadrature_state) { - case STATE(0, 1, 0, 0): - ao_quadrature_count++; - break; - case STATE(1, 0, 0, 0): - ao_quadrature_count--; - break; - default: - return; + for (q = 0; q < AO_QUADRATURE_COUNT; q++) { + switch (ao_quadrature_state[q]) { + case STATE(0, 1, 0, 0): + ao_quadrature_count[q]++; + break; + case STATE(1, 0, 0, 0): + ao_quadrature_count[q]--; + break; + default: + continue; + } + ao_wakeup(&ao_quadrature_count[q]); } - ao_wakeup(&ao_quadrature_count); } int32_t -ao_quadrature_poll(void) +ao_quadrature_poll(uint8_t q) { int32_t ret; - ao_arch_critical(ret = ao_quadrature_count;); + ao_arch_critical(ret = ao_quadrature_count[q];); return ret; } int32_t -ao_quadrature_wait(void) +ao_quadrature_wait(uint8_t q) { - ao_sleep(&ao_quadrature_count); - return ao_quadrature_poll(); + ao_sleep(&ao_quadrature_count[q]); + return ao_quadrature_poll(q); } static void @@ -68,7 +85,7 @@ ao_quadrature_test(void) for (;;) { int32_t c; flush(); - c = ao_quadrature_wait(); + c = ao_quadrature_wait(0); printf ("new count %6d\n", c); if (c == 100) break; @@ -99,19 +116,28 @@ static const struct ao_cmds ao_quadrature_cmds[] = { { 0, NULL } }; +#define init(q) do { \ + ao_enable_port(port(q)); \ + \ + ao_exti_setup(port(q), bita(q), \ + AO_QUADRATURE_MODE|AO_EXTI_MODE_FALLING|AO_EXTI_MODE_RISING|AO_EXTI_PRIORITY_MED, \ + ao_quadrature_isr); \ + ao_exti_enable(port(q), bita(q)); \ + \ + ao_exti_setup(port(q), bitb(q), \ + AO_QUADRATURE_MODE|AO_EXTI_MODE_FALLING|AO_EXTI_MODE_RISING|AO_EXTI_PRIORITY_MED, \ + ao_quadrature_isr); \ + ao_exti_enable(port(q), bitb(q)); \ + } while (0) + void ao_quadrature_init(void) { - ao_quadrature_count = 0; - - ao_enable_port(AO_QUADRATURE_PORT); - ao_exti_setup(AO_QUADRATURE_PORT, AO_QUADRATURE_A, - AO_EXTI_MODE_PULL_UP|AO_EXTI_MODE_FALLING|AO_EXTI_MODE_RISING|AO_EXTI_PRIORITY_MED, - ao_quadrature_isr); - ao_exti_enable(AO_QUADRATURE_PORT, AO_QUADRATURE_A); - ao_exti_setup(AO_QUADRATURE_PORT, AO_QUADRATURE_B, - AO_EXTI_MODE_PULL_UP|AO_EXTI_MODE_FALLING|AO_EXTI_MODE_RISING|AO_EXTI_PRIORITY_MED, - ao_quadrature_isr); - ao_exti_enable(AO_QUADRATURE_PORT, AO_QUADRATURE_B); +#if AO_QUADRATURE_COUNT > 0 + init(0); +#endif +#if AO_QUADRATURE_COUNT > 1 + init(1); +#endif ao_cmd_register(&ao_quadrature_cmds[0]); } diff --git a/src/drivers/ao_quadrature.h b/src/drivers/ao_quadrature.h index 7e1048bc..f0b73b68 100644 --- a/src/drivers/ao_quadrature.h +++ b/src/drivers/ao_quadrature.h @@ -19,10 +19,10 @@ #define _AO_QUADRATURE_H_ int32_t -ao_quadrature_wait(void); +ao_quadrature_wait(uint8_t q); int32_t -ao_quadrature_poll(void); +ao_quadrature_poll(uint8_t q); void ao_quadrature_init(void); diff --git a/src/stm-demo/ao_pins.h b/src/stm-demo/ao_pins.h index 1f5ef4ff..0c1ed8fc 100644 --- a/src/stm-demo/ao_pins.h +++ b/src/stm-demo/ao_pins.h @@ -170,8 +170,15 @@ struct ao_adc { #define HAS_I2C_2 0 #define I2C_2_PB10_PB11 0 -#define AO_QUADRATURE_PORT &stm_gpioc -#define AO_QUADRATURE_A 1 -#define AO_QUADRATURE_B 0 +#define AO_QUADRATURE_COUNT 2 +#define AO_QUADRATURE_MODE AO_EXTI_MODE_PULL_UP + +#define AO_QUADRATURE_0_PORT &stm_gpioc +#define AO_QUADRATURE_0_A 1 +#define AO_QUADRATURE_0_B 0 + +#define AO_QUADRATURE_1_PORT &stm_gpioc +#define AO_QUADRATURE_1_A 3 +#define AO_QUADRATURE_1_B 2 #endif /* _AO_PINS_H_ */ -- cgit v1.2.3 From 46f87373bc8c28442273ee4f8da3a352223150f5 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 6 Aug 2012 22:53:52 -0700 Subject: altos: Add button driver and event queue With this, a single task can wait for any button or quadrature input device. Signed-off-by: Keith Packard --- src/core/ao.h | 7 ++++++- src/drivers/ao_quadrature.c | 7 +++++++ src/stm-demo/Makefile | 4 +++- src/stm-demo/ao_demo.c | 20 ++++++++++++++++++++ src/stm-demo/ao_pins.h | 14 ++++++++++++++ src/stm/ao_timer.c | 2 +- 6 files changed, 51 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/core/ao.h b/src/core/ao.h index 1032dd33..5e1fbb9d 100644 --- a/src/core/ao.h +++ b/src/core/ao.h @@ -125,7 +125,12 @@ ao_panic(uint8_t reason); * ao_timer.c */ -extern volatile __data uint16_t ao_tick_count; +#ifndef AO_TICK_TYPE +#define AO_TICK_TYPE uint16_t +#define AO_TICK_SIGNED int16_t +#endif + +extern volatile __data AO_TICK_TYPE ao_tick_count; /* Our timer runs at 100Hz */ #define AO_HERTZ 100 diff --git a/src/drivers/ao_quadrature.c b/src/drivers/ao_quadrature.c index aed4999e..6a2c1bba 100644 --- a/src/drivers/ao_quadrature.c +++ b/src/drivers/ao_quadrature.c @@ -18,6 +18,12 @@ #include #include #include +#if AO_EVENT +#include +#define ao_quadrature_queue(q) ao_event_put_isr(AO_EVENT_QUADRATURE, q, ao_quadrature_count[q]) +#else +#define ao_quadrature_queue(q) +#endif __xdata int32_t ao_quadrature_count[AO_QUADRATURE_COUNT]; @@ -59,6 +65,7 @@ ao_quadrature_isr(void) default: continue; } + ao_quadrature_queue(q); ao_wakeup(&ao_quadrature_count[q]); } } diff --git a/src/stm-demo/Makefile b/src/stm-demo/Makefile index 52bb7b51..340967fc 100644 --- a/src/stm-demo/Makefile +++ b/src/stm-demo/Makefile @@ -35,7 +35,9 @@ ALTOS_SRC = \ ao_i2c_stm.c \ ao_usb_stm.c \ ao_exti_stm.c \ - ao_quadrature.c + ao_event.c \ + ao_quadrature.c \ + ao_button.c PRODUCT=StmDemo-v0.0 PRODUCT_DEF=-DSTM_DEMO diff --git a/src/stm-demo/ao_demo.c b/src/stm-demo/ao_demo.c index 1b9813fe..fe7c69f2 100644 --- a/src/stm-demo/ao_demo.c +++ b/src/stm-demo/ao_demo.c @@ -17,7 +17,9 @@ #include "ao.h" #include +#include #include +#include struct ao_task demo_task; @@ -150,12 +152,29 @@ ao_temp (void) printf ("temp: %d\n", temp); } +static void +ao_event(void) +{ + struct ao_event event; + + for (;;) { + flush(); + ao_event_get(&event); + printf ("type %1d unit %1d tick %5u value %ld\n", + event.type, event.unit, event.tick, event.value); + if (event.value == 100) + break; + } + +} + __code struct ao_cmds ao_demo_cmds[] = { { ao_dma_test, "D\0DMA test" }, { ao_spi_write, "W\0SPI write" }, { ao_spi_read, "R\0SPI read" }, { ao_i2c_write, "i\0I2C write" }, { ao_temp, "t\0Show temp" }, + { ao_event, "e\0Monitor event queue" }, { 0, NULL } }; @@ -174,6 +193,7 @@ main(void) ao_i2c_init(); ao_exti_init(); ao_quadrature_init(); + ao_button_init(); ao_timer_set_adc_interval(100); diff --git a/src/stm-demo/ao_pins.h b/src/stm-demo/ao_pins.h index 0c1ed8fc..77e42a28 100644 --- a/src/stm-demo/ao_pins.h +++ b/src/stm-demo/ao_pins.h @@ -170,6 +170,8 @@ struct ao_adc { #define HAS_I2C_2 0 #define I2C_2_PB10_PB11 0 +#define AO_EVENT 1 + #define AO_QUADRATURE_COUNT 2 #define AO_QUADRATURE_MODE AO_EXTI_MODE_PULL_UP @@ -181,4 +183,16 @@ struct ao_adc { #define AO_QUADRATURE_1_A 3 #define AO_QUADRATURE_1_B 2 +#define AO_BUTTON_COUNT 2 +#define AO_BUTTON_MODE AO_EXTI_MODE_PULL_UP + +#define AO_BUTTON_0_PORT &stm_gpioc +#define AO_BUTTON_0 6 + +#define AO_BUTTON_1_PORT &stm_gpioc +#define AO_BUTTON_1 7 + +#define AO_TICK_TYPE uint32_t +#define AO_TICK_SIGNED int32_t + #endif /* _AO_PINS_H_ */ diff --git a/src/stm/ao_timer.c b/src/stm/ao_timer.c index ebe75366..adec7aad 100644 --- a/src/stm/ao_timer.c +++ b/src/stm/ao_timer.c @@ -17,7 +17,7 @@ #include "ao.h" -volatile __data uint16_t ao_tick_count; +volatile __data AO_TICK_TYPE ao_tick_count; uint16_t ao_time(void) { -- cgit v1.2.3 From c58f3d1a373b20fac3f51037008bcc40955f1348 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 7 Aug 2012 11:30:47 -0700 Subject: altos: Oops. Serial 1 stdin was busted by typo A typo in the symbol used to enable stdin wakeups from serial1 caused the input to pend until some other wakeup occurred. This also makes the serial1 hw flow control pin selects in config 2 work right, although those aren't used by any current product Signed-off-by: Keith Packard --- src/cc1111/ao_serial.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/cc1111/ao_serial.c b/src/cc1111/ao_serial.c index d5431070..48383802 100644 --- a/src/cc1111/ao_serial.c +++ b/src/cc1111/ao_serial.c @@ -135,7 +135,7 @@ ao_serial1_rx_isr(void) __interrupt 3 if (!ao_fifo_full(ao_serial1_rx_fifo)) ao_fifo_insert(ao_serial1_rx_fifo, U1DBUF); ao_wakeup(&ao_serial1_rx_fifo); -#if USE_SERIAL1_STDIN +#if USE_SERIAL_1_STDIN ao_wakeup(&ao_stdin_ready); #endif } @@ -292,7 +292,9 @@ ao_serial_init(void) /* Make the USART pins be controlled by the USART */ P1SEL |= (1 << 6) | (1 << 7); +#if HAS_SERIAL_1_HW_FLOW P1SEL |= (1 << 5) | (1 << 4); +#endif #endif /* UART mode with receiver enabled */ -- cgit v1.2.3 From c7f228503870c44dfd278ede8b0980dbac73d3c7 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 7 Aug 2012 11:32:16 -0700 Subject: altos: Fix .sdcdbrc file for telebt-v0.1 Signed-off-by: Keith Packard --- src/telebt-v0.1/.sdcdbrc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/telebt-v0.1/.sdcdbrc b/src/telebt-v0.1/.sdcdbrc index 710b4a2f..b9f6129c 100644 --- a/src/telebt-v0.1/.sdcdbrc +++ b/src/telebt-v0.1/.sdcdbrc @@ -1 +1,2 @@ ---directory=.. +--directory=../cc1111:../product:../core:../drivers:. + -- cgit v1.2.3