diff --git a/components/esp_driver_bitscrambler/test_apps/bitscrambler/main/CMakeLists.txt b/components/esp_driver_bitscrambler/test_apps/bitscrambler/main/CMakeLists.txt index d86e1c9cee..f7e31b212a 100644 --- a/components/esp_driver_bitscrambler/test_apps/bitscrambler/main/CMakeLists.txt +++ b/components/esp_driver_bitscrambler/test_apps/bitscrambler/main/CMakeLists.txt @@ -18,3 +18,5 @@ target_bitscrambler_add_src("timeout.bsasm") target_bitscrambler_add_src("trivial.bsasm") target_bitscrambler_add_src("eof_upstream.bsasm") target_bitscrambler_add_src("eof_downstream.bsasm") +target_bitscrambler_add_src("lut32.bsasm") +target_bitscrambler_add_src("loop.bsasm") diff --git a/components/esp_driver_bitscrambler/test_apps/bitscrambler/main/loop.bsasm b/components/esp_driver_bitscrambler/test_apps/bitscrambler/main/loop.bsasm new file mode 100644 index 0000000000..a3146870a2 --- /dev/null +++ b/components/esp_driver_bitscrambler/test_apps/bitscrambler/main/loop.bsasm @@ -0,0 +1,38 @@ +# SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: Unlicense OR CC0-1.0 + +cfg prefetch false +cfg eof_on downstream +cfg trailing_bytes 32 +cfg lut_width_bits 32 + +# WS2812 symbol definition in RMT data format +lut 0x80030009 # Zero +lut 0x80090003 # One +lut 0x00F000F0 # Reset + +# Output the WS2812 reset symbol first +# The reset code is saved in LUT index 2 (0b10) +set 17 H, set 16 L +set 31..0 L31..L0, write 32 + +byteloop: + # Load one byte into counter B + # the read byte will be save to the MSB of the input FIFO, i.e. [63:56] + read 8, set 16..23 56..63, ldctibl + +bitloop: + # Output MSB of byte as LUT index (0 or 1) + set 16 B7 + + # Write LUT output + set 31..0 L31..L0, write 32 + + # Shift BL up by one bit + set 16 L, set 17..23 B0..B6, ldctibl + + # Do this for all 8 bits + loopa 7 1 bitloop + + # All bits are done, handle next byte + jmp byteloop diff --git a/components/esp_driver_bitscrambler/test_apps/bitscrambler/main/lut32.bsasm b/components/esp_driver_bitscrambler/test_apps/bitscrambler/main/lut32.bsasm new file mode 100644 index 0000000000..c3c8932384 --- /dev/null +++ b/components/esp_driver_bitscrambler/test_apps/bitscrambler/main/lut32.bsasm @@ -0,0 +1,21 @@ +# SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: Unlicense OR CC0-1.0 + +cfg prefetch false # disable data prefetch +cfg eof_on downstream # set EOF on downstream +cfg trailing_bytes 4 +cfg lut_width_bits 32 + +# Define contents that stored in the lookup table +lut 0xF0011111 # index 0 +lut 0xF0022222 # index 1 +lut 0xF0033333 # index 2 +lut 0xF0004444 # index 3 + +set 16..17 L # set LUT index: 0 (0b00) + +loop: + read 8, + set 31..0 L31..L0, + write 32, + jmp loop diff --git a/components/esp_driver_bitscrambler/test_apps/bitscrambler/main/test_bitscrambler.c b/components/esp_driver_bitscrambler/test_apps/bitscrambler/main/test_bitscrambler.c index 26cf777b66..87f292f47f 100644 --- a/components/esp_driver_bitscrambler/test_apps/bitscrambler/main/test_bitscrambler.c +++ b/components/esp_driver_bitscrambler/test_apps/bitscrambler/main/test_bitscrambler.c @@ -15,6 +15,8 @@ BITSCRAMBLER_PROGRAM(bitscrambler_program_trivial, "trivial"); BITSCRAMBLER_PROGRAM(bitscrambler_program_timeout, "timeout"); BITSCRAMBLER_PROGRAM(bitscrambler_program_eof_upstream, "eof_upstream"); BITSCRAMBLER_PROGRAM(bitscrambler_program_eof_downstream, "eof_downstream"); +BITSCRAMBLER_PROGRAM(bitscrambler_program_lut32, "lut32"); +BITSCRAMBLER_PROGRAM(bitscrambler_program_loop, "loop"); TEST_CASE("Basic BitScrambler I/O", "[bs]") { @@ -114,3 +116,87 @@ TEST_CASE("BitScrambler with EOF counted on downstream", "[bs]") free(data_in); free(data_out); } + +TEST_CASE("BitScrambler with LUT32", "[bs]") +{ + const size_t len = 32; + uint8_t *data_in = heap_caps_aligned_calloc(8, 1, len, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); + uint32_t *data_out = heap_caps_aligned_calloc(8, 1, len * 4, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); + TEST_ASSERT_NOT_NULL(data_in); + TEST_ASSERT_NOT_NULL(data_out); + + bitscrambler_handle_t bs; + TEST_ESP_OK(bitscrambler_loopback_create(&bs, SOC_BITSCRAMBLER_ATTACH_I2S0, len * 4)); + TEST_ESP_OK(bitscrambler_load_program(bs, bitscrambler_program_lut32)); + size_t res_len = 0; + TEST_ESP_OK(bitscrambler_loopback_run(bs, data_in, len, data_out, len * 4, &res_len)); + bitscrambler_free(bs); + + printf("BitScrambler program complete. Input %zu, output %zu bytes:\n", len, res_len); + for (size_t i = 0; i < res_len / 4; i++) { + printf("%08lX ", data_out[i]); + switch (i % 4) { + case 0: + TEST_ASSERT_EQUAL(0xF0011111, data_out[i]); + break; + case 1: + TEST_ASSERT_EQUAL(0xF0022222, data_out[i]); + break; + case 2: + TEST_ASSERT_EQUAL(0xF0033333, data_out[i]); + break; + case 3: + TEST_ASSERT_EQUAL(0xF0004444, data_out[i]); + printf("\n"); + break; + } + } + TEST_ASSERT_EQUAL(len * 4, res_len); + + free(data_in); + free(data_out); +} + +TEST_CASE("BitScrambler with loop instruction", "[bs]") +{ + uint8_t data_in[] = {0x00, 0xFF, 0x55}; + size_t len = sizeof(data_in) / sizeof(data_in[0]) * 64; + uint32_t *data_out = heap_caps_aligned_calloc(8, 1, len, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); + TEST_ASSERT_NOT_NULL(data_out); + + bitscrambler_handle_t bs; + TEST_ESP_OK(bitscrambler_loopback_create(&bs, SOC_BITSCRAMBLER_ATTACH_I2S0, len)); + TEST_ESP_OK(bitscrambler_load_program(bs, bitscrambler_program_loop)); + size_t res_len = 0; + TEST_ESP_OK(bitscrambler_loopback_run(bs, data_in, sizeof(data_in) / sizeof(data_in[0]), data_out, len, &res_len)); + bitscrambler_free(bs); + + printf("BitScrambler program complete. Input %zu, output %zu bytes:\n", sizeof(data_in) / sizeof(data_in[0]), res_len); + TEST_ASSERT_EQUAL(sizeof(data_in) / sizeof(data_in[0]) * 32 + 4, res_len); + printf("%08lX\r\n", data_out[0]); // reset code + TEST_ASSERT_EQUAL(0x00F000F0, data_out[0]); + // encoding result for 0x00 + for (size_t i = 1; i < 9; i++) { + printf("%08lX ", data_out[i]); + TEST_ASSERT_EQUAL(0x80030009, data_out[i]); + } + printf("\n"); + // encoding result for 0xFF + for (size_t i = 9; i < 17; i++) { + printf("%08lX ", data_out[i]); + TEST_ASSERT_EQUAL(0x80090003, data_out[i]); + } + printf("\n"); + // encoding result for 0x55 + for (size_t i = 17; i < 25; i++) { + printf("%08lX ", data_out[i]); + if (i & 0x01) { + TEST_ASSERT_EQUAL(0x80030009, data_out[i]); + } else { + TEST_ASSERT_EQUAL(0x80090003, data_out[i]); + } + } + printf("\n"); + + free(data_out); +}