summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/.gitignore1
-rw-r--r--src/Makefile6
-rw-r--r--src/drivers/ao_cc1120.c87
-rw-r--r--src/drivers/ao_cc1120_CC1120.h28
-rw-r--r--src/drivers/ao_fec.h60
-rw-r--r--src/drivers/ao_fec_tx.c139
-rw-r--r--src/megametrum-v0.1/Makefile3
-rw-r--r--src/test/Makefile7
-rw-r--r--src/test/ao_fec_tx_test.c47
-rw-r--r--src/util/make-whiten37
10 files changed, 372 insertions, 43 deletions
diff --git a/src/.gitignore b/src/.gitignore
index c6e1e353..cae36ae6 100644
--- a/src/.gitignore
+++ b/src/.gitignore
@@ -1,2 +1,3 @@
altitude.h
altitude-pa.h
+ao_whiten.h
diff --git a/src/Makefile b/src/Makefile
index c2e324c4..3fca2ab2 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -6,6 +6,7 @@
vpath make-altitude util
vpath make-altitude-pa util
vpath make-kalman util
+vpath make-whiten util
vpath kalman.5c kalman
vpath kalman_filter.5c kalman
vpath load_csv.5c kalman
@@ -46,7 +47,7 @@ uninstall:
all-recursive: all-local
-all-local: altitude.h altitude-pa.h ao_kalman.h
+all-local: altitude.h altitude-pa.h ao_kalman.h ao_whiten.h
altitude.h: make-altitude
nickle $< > $@
@@ -57,5 +58,8 @@ altitude-pa.h: make-altitude-pa
ao_kalman.h: make-kalman kalman.5c kalman_filter.5c load_csv.5c matrix.5c
bash $< kalman > $@
+ao_whiten.h: make-whiten
+ nickle $< > $@
+
clean-local:
rm -f altitude.h ao_kalman.h
diff --git a/src/drivers/ao_cc1120.c b/src/drivers/ao_cc1120.c
index f06d52ca..231d14d4 100644
--- a/src/drivers/ao_cc1120.c
+++ b/src/drivers/ao_cc1120.c
@@ -18,6 +18,7 @@
#include <ao.h>
#include <ao_cc1120.h>
#include <ao_exti.h>
+#include <ao_fec.h>
uint8_t ao_radio_wake;
uint8_t ao_radio_mutex;
@@ -240,26 +241,27 @@ ao_radio_rx_done(void)
return ao_radio_marc_status() == CC1120_MARC_STATUS1_RX_FINISHED;
}
+static void
+ao_radio_start_tx(void)
+{
+ ao_radio_reg_write(CC1120_IOCFG2, CC1120_IOCFG_GPIO_CFG_RX0TX1_CFG);
+ ao_exti_enable(&AO_CC1120_INT_PORT, AO_CC1120_INT_PIN);
+ ao_radio_strobe(CC1120_STX);
+}
+
void
ao_radio_rdf(uint8_t len)
{
int i;
ao_radio_get(len);
- ao_radio_abort = 0;
ao_radio_wake = 0;
for (i = 0; i < sizeof (rdf_setup) / sizeof (rdf_setup[0]); i += 2)
ao_radio_reg_write(rdf_setup[i], rdf_setup[i+1]);
- ao_radio_reg_write(CC1120_IOCFG2, CC1120_IOCFG_GPIO_CFG_RX0TX1_CFG);
-
ao_radio_fifo_write_fixed(ao_radio_rdf_value, len);
- ao_radio_reg_write(CC1120_PKT_LEN, len);
-
- ao_exti_enable(&AO_CC1120_INT_PORT, AO_CC1120_INT_PIN);
-
- ao_radio_strobe(CC1120_STX);
+ ao_radio_start_tx();
cli();
while (!ao_radio_wake && !ao_radio_abort)
@@ -327,24 +329,45 @@ ao_radio_test(void)
void
ao_radio_send(void *d, uint8_t size)
{
- uint8_t marc_status;
-
+ uint8_t marc_status;
+ static uint8_t prepare[128];
+ uint8_t prepare_len;
+ static uint8_t encode[256];
+ uint8_t encode_len;
+ static uint8_t interleave[256];
+ uint8_t interleave_len;
+
+ ao_fec_dump_bytes(d, size, "Input");
+
+#if 1
+ prepare_len = ao_fec_prepare(d, size, prepare);
+ ao_fec_dump_bytes(prepare, prepare_len, "Prepare");
+
+ ao_fec_whiten(prepare, prepare_len, prepare);
+ ao_fec_dump_bytes(prepare, prepare_len, "Whiten");
+
+ encode_len = ao_fec_encode(prepare, prepare_len, encode);
+ ao_fec_dump_bytes(encode, encode_len, "Encode");
+
+ interleave_len = ao_fec_interleave(encode, encode_len, interleave);
+ ao_fec_dump_bytes(interleave, interleave_len, "Interleave");
+ ao_radio_get(interleave_len);
+ ao_radio_fifo_write(interleave, interleave_len);
+#else
ao_radio_get(size);
- ao_radio_wake = 0;
ao_radio_fifo_write(d, size);
- ao_exti_enable(&AO_CC1120_INT_PORT, AO_CC1120_INT_PIN);
- ao_radio_strobe(CC1120_STX);
+#endif
+
+ ao_radio_wake = 0;
+
+ ao_radio_start_tx();
+
cli();
- for (;;) {
- if (ao_radio_wake) {
- marc_status = ao_radio_marc_status();
- if (marc_status != CC1120_MARC_STATUS1_NO_FAILURE)
- break;
- ao_radio_wake = 0;
- }
+ while (!ao_radio_wake && !ao_radio_abort)
ao_sleep(&ao_radio_wake);
- }
sei();
+ if (!ao_radio_tx_done())
+ ao_radio_idle();
ao_radio_put();
}
@@ -361,6 +384,7 @@ ao_radio_recv(__xdata void *d, uint8_t size)
cli();
for (;;) {
if (ao_radio_abort)
+
break;
if (ao_radio_wake) {
marc_status = ao_radio_marc_status();
@@ -413,7 +437,7 @@ static const uint16_t packet_setup[] = {
CC1120_DRATE0, ((PACKET_DRATE_M >> 0) & 0xff),
CC1120_PKT_CFG2, ((CC1120_PKT_CFG2_CCA_MODE_ALWAYS_CLEAR << CC1120_PKT_CFG2_CCA_MODE) |
(CC1120_PKT_CFG2_PKT_FORMAT_NORMAL << CC1120_PKT_CFG2_PKT_FORMAT)),
- CC1120_PKT_CFG1, ((1 << CC1120_PKT_CFG1_WHITE_DATA) |
+ CC1120_PKT_CFG1, ((0 << CC1120_PKT_CFG1_WHITE_DATA) |
(CC1120_PKT_CFG1_ADDR_CHECK_CFG_NONE << CC1120_PKT_CFG1_ADDR_CHECK_CFG) |
(CC1120_PKT_CFG1_CRC_CFG_DISABLED << CC1120_PKT_CFG1_CRC_CFG) |
(1 << CC1120_PKT_CFG1_APPEND_STATUS)),
@@ -469,9 +493,6 @@ ao_radio_setup(void)
for (i = 0; i < sizeof (radio_setup) / sizeof (radio_setup[0]); i += 2)
ao_radio_reg_write(radio_setup[i], radio_setup[i+1]);
- /* Enable marc status interrupt on gpio 2 pin */
- ao_radio_reg_write(CC1120_IOCFG2, CC1120_IOCFG_GPIO_CFG_MARC_MCU_WAKEUP);
-
ao_radio_set_packet();
ao_config_get();
@@ -707,6 +728,21 @@ static void ao_radio_beep(void) {
ao_radio_rdf(RDF_PACKET_LEN);
}
+static void ao_radio_packet(void) {
+ static uint8_t packet[] = {
+#if 1
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+#else
+ 3, 1, 2, 3
+#endif
+ };
+
+ ao_radio_send(packet, sizeof (packet));
+}
+
#endif
static const struct ao_cmds ao_radio_cmds[] = {
@@ -714,6 +750,7 @@ static const struct ao_cmds ao_radio_cmds[] = {
#if CC1120_DEBUG
{ ao_radio_show, "R\0Show CC1120 status" },
{ ao_radio_beep, "b\0Emit an RDF beacon" },
+ { ao_radio_packet, "p\0Send a test packet" },
#endif
{ 0, NULL }
};
diff --git a/src/drivers/ao_cc1120_CC1120.h b/src/drivers/ao_cc1120_CC1120.h
index c900b7f9..c0f35a23 100644
--- a/src/drivers/ao_cc1120_CC1120.h
+++ b/src/drivers/ao_cc1120_CC1120.h
@@ -21,29 +21,27 @@
*
***************************************************************/
- CC1120_SYNC3, 0x93, /* Sync Word Configuration [31:24] */
- CC1120_SYNC2, 0x0b, /* Sync Word Configuration [23:16] */
- CC1120_SYNC1, 0x51, /* Sync Word Configuration [15:8] */
- CC1120_SYNC0, 0xde, /* Sync Word Configuration [7:0] */
+ CC1120_SYNC3, 0xD3, /* Sync Word Configuration [31:24] */
+ CC1120_SYNC2, 0x91, /* Sync Word Configuration [23:16] */
+ CC1120_SYNC1, 0xD3, /* Sync Word Configuration [15:8] */
+ CC1120_SYNC0, 0x91, /* Sync Word Configuration [7:0] */
+
CC1120_SYNC_CFG1, 0x08, /* Sync Word Detection Configuration */
- CC1120_SYNC_CFG0, 0x17, /* Sync Word Length Configuration */
-#if 0
- CC1120_DEVIATION_M, 0x50, /* Frequency Deviation Configuration */
- CC1120_MODCFG_DEV_E, 0x0d, /* Modulation Format and Frequency Deviation Configuration */
-#endif
+ CC1120_SYNC_CFG0,
+ (CC1120_SYNC_CFG0_SYNC_MODE_16_BITS << CC1120_SYNC_CFG0_SYNC_MODE) |
+ (CC1120_SYNC_CFG0_SYNC_NUM_ERROR_2 << CC1120_SYNC_CFG0_SYNC_NUM_ERROR),
CC1120_DCFILT_CFG, 0x1c, /* Digital DC Removal Configuration */
- CC1120_PREAMBLE_CFG1, 0x18, /* Preamble Length Configuration */
+ CC1120_PREAMBLE_CFG1, /* Preamble Length Configuration */
+ (CC1120_PREAMBLE_CFG1_NUM_PREAMBLE_4_BYTES << CC1120_PREAMBLE_CFG1_NUM_PREAMBLE) |
+ (CC1120_PREAMBLE_CFG1_PREAMBLE_WORD_AA << CC1120_PREAMBLE_CFG1_PREAMBLE_WORD),
CC1120_PREAMBLE_CFG0, 0x2a, /* */
CC1120_FREQ_IF_CFG, 0x40, /* RX Mixer Frequency Configuration */
CC1120_IQIC, 0x46, /* Digital Image Channel Compensation Configuration */
CC1120_CHAN_BW, 0x02, /* Channel Filter Configuration */
+
CC1120_MDMCFG1, 0x46, /* General Modem Parameter Configuration */
CC1120_MDMCFG0, 0x05, /* General Modem Parameter Configuration */
-#if 0
- CC1120_DRATE2, 0x93, /* Data Rate Configuration Exponent and Mantissa [19:16] */
- CC1120_DRATE1, 0xa4, /* Data Rate Configuration Mantissa [15:8] */
- CC1120_DRATE0, 0x00, /* Data Rate Configuration Mantissa [7:0] */
-#endif
+
CC1120_AGC_REF, 0x20, /* AGC Reference Level Configuration */
CC1120_AGC_CS_THR, 0x19, /* Carrier Sense Threshold Configuration */
CC1120_AGC_GAIN_ADJUST, 0x00, /* RSSI Offset Configuration */
diff --git a/src/drivers/ao_fec.h b/src/drivers/ao_fec.h
new file mode 100644
index 00000000..db5523a3
--- /dev/null
+++ b/src/drivers/ao_fec.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright © 2012 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; 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_FEC_H_
+#define _AO_FEC_H_
+
+#include <stdint.h>
+
+#define AO_FEC_CRC_INIT 0xffff
+#define AO_FEC_TRELLIS_TERMINATOR 0x0b
+#define AO_FEC_PREPARE_EXTRA 4
+
+void
+ao_fec_dump_bytes(uint8_t *bytes, uint8_t len, char *name);
+
+uint16_t
+ao_fec_crc(uint8_t *bytes, uint8_t len);
+
+/*
+ * Append CRC and terminator bytes, returns resulting length.
+ * 'out' must be at least len + AO_FEC_PREPARE_EXTRA bytes long
+ */
+uint8_t
+ao_fec_prepare(uint8_t *in, uint8_t len, uint8_t *out);
+
+/*
+ * Whiten data using the cc1111 PN9 sequence. 'out'
+ * must be 'len' bytes long. 'out' and 'in' can be
+ * the same array
+ */
+uint8_t
+ao_fec_whiten(uint8_t *in, uint8_t len, uint8_t *out);
+
+/*
+ * Encode data. 'out' must be len*2 bytes long
+ */
+uint8_t
+ao_fec_encode(uint8_t *in, uint8_t len, uint8_t *out);
+
+/*
+ * Interleave data. 'out' must be 'len' bytes long
+ */
+uint8_t
+ao_fec_interleave(uint8_t *in, uint8_t len, uint8_t *out);
+
+#endif /* _AO_FEC_H_ */
diff --git a/src/drivers/ao_fec_tx.c b/src/drivers/ao_fec_tx.c
new file mode 100644
index 00000000..b8933956
--- /dev/null
+++ b/src/drivers/ao_fec_tx.c
@@ -0,0 +1,139 @@
+/*
+ * Copyright © 2012 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; 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_fec.h>
+#include <stdio.h>
+
+void
+ao_fec_dump_bytes(uint8_t *bytes, uint8_t len, char *name)
+{
+ uint8_t i;
+
+ printf ("%s (%d):", name, len);
+ for (i = 0; i < len; i++) {
+ if ((i & 7) == 0)
+ printf ("\n\t%02x:", i);
+ printf(" %02x", bytes[i]);
+ }
+ printf ("\n");
+}
+
+static uint16_t inline
+crc_byte(uint8_t byte, uint16_t crc)
+{
+ uint8_t bit;
+
+ for (bit = 0; bit < 8; bit++) {
+ if (((crc & 0x8000) >> 8) ^ (byte & 0x80))
+ crc = (crc << 1) ^ 0x8005;
+ else
+ crc = (crc << 1);
+ byte <<= 1;
+ }
+ return crc;
+}
+
+uint16_t
+ao_fec_crc(uint8_t *bytes, uint8_t len)
+{
+ uint16_t crc = AO_FEC_CRC_INIT;
+
+ while (len--)
+ crc = crc_byte(*bytes++, crc);
+ return crc;
+}
+
+uint8_t
+ao_fec_prepare(uint8_t *in, uint8_t len, uint8_t *out)
+{
+ uint16_t crc = ao_fec_crc (in, len);
+ uint8_t i;
+ uint8_t num_fec;
+
+ /* Copy data */
+ for (i = 0; i < len; i++)
+ out[i] = in[i];
+
+ /* Append CRC */
+ out[i++] = crc >> 8;
+ out[i++] = crc;
+
+ /* Append FEC -- 1 byte if odd, two bytes if even */
+ num_fec = 2 - (i & 1);
+ while (num_fec--)
+ out[i++] = AO_FEC_TRELLIS_TERMINATOR;
+ return i;
+}
+
+static const uint8_t whiten[] = {
+#include "ao_whiten.h"
+};
+
+uint8_t
+ao_fec_whiten(uint8_t *in, uint8_t len, uint8_t *out)
+{
+ const uint8_t *w = whiten;
+
+ while (len--)
+ *out++ = *in++ ^ *w++;
+}
+
+static const uint8_t ao_fec_encode_table[16] = {
+ 0, 3, 1, 2,
+ 3, 0, 2, 1,
+ 3, 0, 2, 1,
+ 0, 3, 1, 2
+};
+
+uint8_t
+ao_fec_encode(uint8_t *in, uint8_t len, uint8_t *out)
+{
+ uint16_t fec = 0, output;
+ uint8_t byte, bit;
+
+ for (byte = 0; byte < len; byte++) {
+ fec = (fec & 0x700) | in[byte];
+ output = 0;
+ for (bit = 0; bit < 8; bit++) {
+ output = output << 2 | ao_fec_encode_table[fec >> 7];
+ fec = (fec << 1) & 0x7ff;
+ }
+ out[byte * 2] = output >> 8;
+ out[byte * 2 + 1] = output;
+ }
+ return len * 2;
+}
+
+uint8_t
+ao_fec_interleave(uint8_t *in, uint8_t len, uint8_t *out)
+{
+ uint8_t i, j;
+
+ for (i = 0; i < len; i += 4) {
+ uint32_t interleaved = 0;
+
+ for (j = 0; j < 4 * 4; j++) {
+ interleaved <<= 2;
+ interleaved |= (in[i + (~j & 0x3)] >> (2 * ((j & 0xc) >> 2))) & 0x03;
+ }
+ out[i+0] = interleaved >> 24;
+ out[i+1] = interleaved >> 16;
+ out[i+2] = interleaved >> 8;
+ out[i+3] = interleaved;
+ }
+ return len;
+}
diff --git a/src/megametrum-v0.1/Makefile b/src/megametrum-v0.1/Makefile
index 5761fed7..054855ba 100644
--- a/src/megametrum-v0.1/Makefile
+++ b/src/megametrum-v0.1/Makefile
@@ -18,6 +18,8 @@ INC = \
ao_ms5607.h \
ao_hmc5883.h \
ao_mpu6000.h \
+ ao_cc1120_CC1120.h \
+ ao_whiten.h \
stm32l.h
#
@@ -45,6 +47,7 @@ ALTOS_SRC = \
ao_dma_stm.c \
ao_spi_stm.c \
ao_cc1120.c \
+ ao_fec_tx.c \
ao_ms5607.c \
ao_adc_stm.c \
ao_beep_stm.c \
diff --git a/src/test/Makefile b/src/test/Makefile
index 1e54f5e0..3e308dd7 100644
--- a/src/test/Makefile
+++ b/src/test/Makefile
@@ -1,6 +1,6 @@
vpath % ..:../core:../drivers:../util
-PROGS=ao_flight_test ao_flight_test_baro ao_flight_test_accel ao_flight_test_noisy_accel ao_gps_test ao_gps_test_skytraq ao_convert_test ao_convert_pa_test
+PROGS=ao_flight_test ao_flight_test_baro ao_flight_test_accel ao_flight_test_noisy_accel ao_gps_test ao_gps_test_skytraq ao_convert_test ao_convert_pa_test ao_fec_tx_test
KALMAN=make-kalman
@@ -38,4 +38,7 @@ ao_convert_pa_test: ao_convert_pa_test.c ao_convert_pa.c altitude-pa.h
cc $(CFLAGS) -o $@ $<
ao_kalman.h: $(KALMAN)
- (cd .. && make ao_kalman.h) \ No newline at end of file
+ (cd .. && make ao_kalman.h)
+
+ao_fec_tx_test: ao_fec_tx_test.c ao_fec_tx.c
+ cc $(CFLAGS) -o $@ ao_fec_tx_test.c ../drivers/ao_fec_tx.c
diff --git a/src/test/ao_fec_tx_test.c b/src/test/ao_fec_tx_test.c
new file mode 100644
index 00000000..b8dc9308
--- /dev/null
+++ b/src/test/ao_fec_tx_test.c
@@ -0,0 +1,47 @@
+/*
+ * Copyright © 2012 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; 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_fec.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+int
+main(int argc, char **argv)
+{
+ uint8_t input[4] = { 3, 1, 2, 3 };
+ uint8_t prepare[sizeof(input) + AO_FEC_PREPARE_EXTRA];
+ uint8_t encode[sizeof(prepare) * 2];
+ uint8_t interleave[sizeof(encode)];
+ uint8_t prepare_len;
+ uint8_t encode_len;
+ uint8_t interleave_len;
+
+ ao_fec_dump_bytes(input, sizeof(input), "Input");
+
+ prepare_len = ao_fec_prepare(input, sizeof (input), prepare);
+
+ ao_fec_dump_bytes(prepare, prepare_len, "Prepare");
+
+ encode_len = ao_fec_encode(prepare, prepare_len, encode);
+
+ ao_fec_dump_bytes(encode, encode_len, "Encode");
+
+ interleave_len = ao_fec_interleave(encode, encode_len, interleave);
+
+ ao_fec_dump_bytes(interleave, interleave_len, "Interleave");
+}
+
diff --git a/src/util/make-whiten b/src/util/make-whiten
new file mode 100644
index 00000000..d68a02af
--- /dev/null
+++ b/src/util/make-whiten
@@ -0,0 +1,37 @@
+/*
+ * Copyright © 2012 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; 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.
+ */
+
+/* Generate the data whitening array used by the CC11* radios */
+
+int pn9 = 0x1ff;
+
+void
+pn9_step() {
+ pn9 = (pn9 >> 1) | (((pn9 ^ (pn9 >> 5)) & 1) << 8);
+}
+
+int val()
+{
+ int ret = pn9 & 0xff;
+
+ for (int i = 0; i < 8; i++)
+ pn9_step();
+ return ret;
+}
+
+for (int i = 0; i < 128; i++)
+ printf (" /* %3d */ 0x%02x,\n", i + 1, val());