lib: add support for dual 12 bit FPGA source

This commit is contained in:
Steve Markgraf 2025-03-25 23:58:48 +01:00
parent ff55b5acc6
commit dccfb3a5f2
3 changed files with 47 additions and 8 deletions

View file

@ -108,6 +108,27 @@ enum
PIO_32BIT_IQ, PIO_32BIT_IQ,
PIO_PCM1802_AUDIO, PIO_PCM1802_AUDIO,
// Placeholder for internal ADC data from pico // Placeholder for internal ADC data from pico
FPGA_1BIT = 256,
FPGA_2BIT,
FPGA_3BIT,
FPGA_4BIT,
FPGA_5BIT,
FPGA_6BIT,
FPGA_7BIT,
FPGA_8BIT,
FPGA_8BIT_DUAL,
FPGA_8BIT_DDR,
FPGA_8BIT_IQ,
FPGA_9BIT,
FPGA_10BIT,
FPGA_10BIT_DUAL,
FPGA_10BIT_DDR,
FPGA_10BIT_IQ,
FPGA_11BIT,
FPGA_12BIT,
FPGA_12BIT_DUAL,
FPGA_12BIT_DDR,
FPGA_12BIT_IQ,
}; };
#endif #endif

View file

@ -228,7 +228,7 @@ void hsdaoh_unpack_fpga_12bit_dual(hsdaoh_dev_t *dev, hsdaoh_data_info_t *data_i
{ {
uint16_t *in = (uint16_t *)data_info->buf; uint16_t *in = (uint16_t *)data_info->buf;
size_t inlen = data_info->len / sizeof(uint16_t); size_t inlen = data_info->len / sizeof(uint16_t);
unsigned int i, j = 0; unsigned int j = 0;
uint16_t *out16_1 = malloc(sizeof(uint16_t) * inlen * 2); uint16_t *out16_1 = malloc(sizeof(uint16_t) * inlen * 2);
uint16_t *out16_2 = malloc(sizeof(uint16_t) * inlen * 2); uint16_t *out16_2 = malloc(sizeof(uint16_t) * inlen * 2);
@ -236,7 +236,7 @@ void hsdaoh_unpack_fpga_12bit_dual(hsdaoh_dev_t *dev, hsdaoh_data_info_t *data_i
return; return;
/* extract packed 2x12 bit samples */ /* extract packed 2x12 bit samples */
for (i = 0; i < inlen; i += 3) { for (unsigned int i = 0; i < inlen; i += 3) {
uint16_t lsbs = in[i+2]; uint16_t lsbs = in[i+2];
out16_1[j] = ((in[i+0] & 0xff00) >> 4) | ((lsbs >> 0) & 0xf); out16_1[j] = ((in[i+0] & 0xff00) >> 4) | ((lsbs >> 0) & 0xf);
out16_2[j++] = ((in[i+0] & 0x00ff) << 4) | ((lsbs >> 4) & 0xf); out16_2[j++] = ((in[i+0] & 0x00ff) << 4) | ((lsbs >> 4) & 0xf);
@ -245,10 +245,10 @@ void hsdaoh_unpack_fpga_12bit_dual(hsdaoh_dev_t *dev, hsdaoh_data_info_t *data_i
} }
if (dev->output_float) { if (dev->output_float) {
hsdaoh_16bit_to_float(dev, data_info, out16_1, i, 2047.5, true); hsdaoh_16bit_to_float(dev, data_info, out16_1, j, 2047.5, true);
} else { } else {
data_info->buf = (uint8_t *)out16_1; data_info->buf = (uint8_t *)out16_1;
data_info->len = i * sizeof(uint16_t); data_info->len = j * sizeof(uint16_t);
dev->cb(data_info); dev->cb(data_info);
} }
@ -256,10 +256,10 @@ void hsdaoh_unpack_fpga_12bit_dual(hsdaoh_dev_t *dev, hsdaoh_data_info_t *data_i
data_info->stream_id += 1; data_info->stream_id += 1;
if (dev->output_float) { if (dev->output_float) {
hsdaoh_16bit_to_float(dev, data_info, out16_2, i, 2047.5, true); hsdaoh_16bit_to_float(dev, data_info, out16_2, j, 2047.5, true);
} else { } else {
data_info->buf = (uint8_t *)out16_2; data_info->buf = (uint8_t *)out16_2;
data_info->len = i * sizeof(uint16_t); data_info->len = j * sizeof(uint16_t);
dev->cb(data_info); dev->cb(data_info);
} }

View file

@ -72,6 +72,16 @@ enum crc_config {
CRC16_2_LINE /* Line contains CRC of the line before the last line */ CRC16_2_LINE /* Line contains CRC of the line before the last line */
}; };
#define DEFAULT_MAX_STREAMS 8
typedef struct
{
uint64_t data_cnt;
uint32_t srate;
uint32_t reserved1;
char reserved2[16];
} __attribute__((packed, aligned(1))) stream_info_t;
typedef struct typedef struct
{ {
uint32_t magic; uint32_t magic;
@ -80,6 +90,10 @@ typedef struct
uint8_t crc_config; uint8_t crc_config;
uint16_t version; uint16_t version;
uint32_t flags; uint32_t flags;
uint32_t reserved2[8];
uint16_t stream0_format;
uint16_t max_streamid;
stream_info_t stream_info[DEFAULT_MAX_STREAMS];
} __attribute__((packed, aligned(1))) metadata_t; } __attribute__((packed, aligned(1))) metadata_t;
#define FLAG_STREAM_ID_PRESENT (1 << 0) #define FLAG_STREAM_ID_PRESENT (1 << 0)
@ -552,6 +566,9 @@ void hsdaoh_output(hsdaoh_dev_t *dev, uint16_t sid, int format, uint8_t *data, s
case PIO_PCM1802_AUDIO: case PIO_PCM1802_AUDIO:
hsdaoh_unpack_pio_pcm1802_audio(dev, &data_info); hsdaoh_unpack_pio_pcm1802_audio(dev, &data_info);
break; break;
case FPGA_12BIT_DUAL:
hsdaoh_unpack_fpga_12bit_dual(dev, &data_info);
break;
default: default:
dev->cb(&data_info); dev->cb(&data_info);
break; break;
@ -587,7 +604,6 @@ static void *hsdaoh_output_worker(void *arg)
pthread_mutex_unlock(&dev->ll_mutex); pthread_mutex_unlock(&dev->ll_mutex);
while (curelem != NULL) { while (curelem != NULL) {
// printf("got a buffer for sid %d with len %d\n", curelem->sid, bytesleft);
hsdaoh_output(dev, curelem->sid, curelem->format, curelem->data, curelem->len); hsdaoh_output(dev, curelem->sid, curelem->format, curelem->data, curelem->len);
prev = curelem; prev = curelem;
@ -716,8 +732,10 @@ void hsdaoh_process_frame(hsdaoh_dev_t *dev, uint8_t *data, int size)
if (meta.flags & FLAG_STREAM_ID_PRESENT) if (meta.flags & FLAG_STREAM_ID_PRESENT)
stream_id &= 0x3f; stream_id &= 0x3f;
else else {
stream_id = 0; stream_id = 0;
format = meta.stream0_format;
}
/* we only use 12 bits, the upper 4 bits are reserved for the metadata */ /* we only use 12 bits, the upper 4 bits are reserved for the metadata */
payload_len &= 0x0fff; payload_len &= 0x0fff;