feat(bitscrambler): test loop and lut instructions

This commit is contained in:
morris
2025-03-04 18:55:16 +08:00
parent bcadcb746d
commit 586d41e8a6
4 changed files with 147 additions and 0 deletions

View File

@@ -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")

View File

@@ -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

View File

@@ -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

View File

@@ -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);
}