forked from espressif/esp-idf
feat(bitscrambler): test loop and lut instructions
This commit is contained in:
@@ -18,3 +18,5 @@ target_bitscrambler_add_src("timeout.bsasm")
|
|||||||
target_bitscrambler_add_src("trivial.bsasm")
|
target_bitscrambler_add_src("trivial.bsasm")
|
||||||
target_bitscrambler_add_src("eof_upstream.bsasm")
|
target_bitscrambler_add_src("eof_upstream.bsasm")
|
||||||
target_bitscrambler_add_src("eof_downstream.bsasm")
|
target_bitscrambler_add_src("eof_downstream.bsasm")
|
||||||
|
target_bitscrambler_add_src("lut32.bsasm")
|
||||||
|
target_bitscrambler_add_src("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
|
@@ -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
|
@@ -15,6 +15,8 @@ BITSCRAMBLER_PROGRAM(bitscrambler_program_trivial, "trivial");
|
|||||||
BITSCRAMBLER_PROGRAM(bitscrambler_program_timeout, "timeout");
|
BITSCRAMBLER_PROGRAM(bitscrambler_program_timeout, "timeout");
|
||||||
BITSCRAMBLER_PROGRAM(bitscrambler_program_eof_upstream, "eof_upstream");
|
BITSCRAMBLER_PROGRAM(bitscrambler_program_eof_upstream, "eof_upstream");
|
||||||
BITSCRAMBLER_PROGRAM(bitscrambler_program_eof_downstream, "eof_downstream");
|
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]")
|
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_in);
|
||||||
free(data_out);
|
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);
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user