Skip to content

Commit 294b5a7

Browse files
samples: usb: uac2_implicit: TDM improvement
Extend TDM configuration. For now the configuration requires three parameters: - ISO_IN_CH_CNT - defines also number of TDM RX channels - ISO_OUT_CH_CNT - defines also number of TDM TX channels - TDM_WORD_SIZE - defines also `sample_t` type Signed-off-by: Adam Kondraciuk <[email protected]>
1 parent 41b9e7c commit 294b5a7

File tree

1 file changed

+75
-36
lines changed
  • samples/subsys/usb/uac2_implicit_feedback/flpr/src

1 file changed

+75
-36
lines changed

samples/subsys/usb/uac2_implicit_feedback/flpr/src/main.c

Lines changed: 75 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,20 @@
99
#include <zephyr/logging/log.h>
1010
LOG_MODULE_REGISTER(main, 1);
1111
/* === BUFFERS === */
12-
13-
#define ISO_IN_CH_CNT 1
14-
#define TDM_RX_CH_CNT 2
15-
12+
/* buffers configuration */
13+
#define ISO_IN_CH_CNT 4
1614
#define ISO_OUT_CH_CNT 2
17-
#define TDM_TX_CH_CNT 2
15+
#define TDM_WORD_SIZE 32
16+
17+
#if ISO_IN_CH_CNT > ISO_OUT_CH_CNT
18+
#define TDM_CH_CNT ISO_IN_CH_CNT
19+
#else
20+
#define TDM_CH_CNT ISO_OUT_CH_CNT
21+
#endif
22+
#define TDM_RX_CH_CNT ISO_IN_CH_CNT
23+
#define TDM_TX_CH_CNT ISO_OUT_CH_CNT
1824

1925
#define SAMPLES_NUM 6
20-
#define CHANNELS_NUM 2
2126
#define BUFFERS_NUM 3
2227
#define NEXT_BUFFER(x) ((x + 1) % BUFFERS_NUM)
2328

@@ -38,9 +43,20 @@ LOG_MODULE_REGISTER(main, 1);
3843
#define DBG_PIN_INIT(x)
3944
#endif
4045

46+
#define TDM_GET_MAX_LEN(buf_len, num_of_channels) ((buf_len * TDM_CH_CNT) / num_of_channels)
47+
4148
static struct feedback_ctx * mp_fbck;
4249

50+
typedef enum {
51+
tdm_tx,
52+
tdm_rx
53+
} tdm_dir_t;
54+
55+
#if TDM_WORD_SIZE > 16
56+
typedef uint32_t sample_t;
57+
#else
4358
typedef uint16_t sample_t;
59+
#endif
4460

4561
typedef struct {
4662
void * ptr;
@@ -57,6 +73,15 @@ static uint8_t m_iso_out_idx;
5773
/*static uint32_t m_fake_sample_tx[SAMPLES_NUM + 1] __aligned(4);*/
5874
/*static uint32_t m_fake_sample_rx[SAMPLES_NUM + 1] __aligned(4);*/
5975

76+
#define NRFX_TDM_NUM_OF_CHANNELS (TDM_CONFIG_CHANNEL_NUM_NUM_Max + 1)
77+
78+
#define NRFX_TDM_TX_CHANNELS_MASK \
79+
GENMASK(TDM_CONFIG_CHANNEL_MASK_Tx0Enable_Pos + TDM_CONFIG_CHANNEL_NUM_NUM_Max, \
80+
TDM_CONFIG_CHANNEL_MASK_Tx0Enable_Pos)
81+
#define NRFX_TDM_RX_CHANNELS_MASK \
82+
GENMASK(TDM_CONFIG_CHANNEL_MASK_Rx0Enable_Pos + TDM_CONFIG_CHANNEL_NUM_NUM_Max, \
83+
TDM_CONFIG_CHANNEL_MASK_Rx0Enable_Pos)
84+
6085
static void buffers_flush(void)
6186
{
6287
m_iso_in_idx = 0;
@@ -68,23 +93,24 @@ static void buffers_flush(void)
6893
/* === TDM === */
6994
#define MCKCONST 1048576UL
7095
#define AUDIOPLL_FREQ 12287963UL
71-
#define WORD_SIZE 16UL
96+
#define WORD_SIZE CONCAT(TDM_WORD_SIZE, UL)
7297
#define FRAME_CLK_FREQ 48000UL
73-
#define SCK_FREQ WORD_SIZE * FRAME_CLK_FREQ * CHANNELS_NUM
74-
#define SCK_VALUE ((uint32_t)(((uint64_t)SCK_FREQ * MCKCONST) / (AUDIOPLL_FREQ + (SCK_FREQ / 2) )* 4096))
98+
#define SCK_FREQ WORD_SIZE * FRAME_CLK_FREQ * TDM_CH_CNT
99+
#define SCK_DIV_VALUE ((uint32_t)(((uint64_t)SCK_FREQ * MCKCONST) / (AUDIOPLL_FREQ + (SCK_FREQ / 2) )* 4096))
75100

76101
static const nrf_tdm_config_t m_cfg = {
77102
.mode = NRF_TDM_MODE_MASTER,
78-
.alignment = NRF_TDM_ALIGN_LEFT,
79-
.sample_width = NRF_TDM_SWIDTH_16BIT,
80-
.channels = NRF_TDM_CHANNEL_TX0_MASK | NRF_TDM_CHANNEL_TX1_MASK | NRF_TDM_CHANNEL_RX0_MASK | NRF_TDM_CHANNEL_RX1_MASK,
81-
.num_of_channels = NRF_TDM_CHANNELS_COUNT_2,
82-
.channel_delay = NRF_TDM_CHANNEL_DELAY_1CK,
103+
.sample_width = CONCAT(NRF_TDM_SWIDTH_, TDM_WORD_SIZE, BIT),
104+
.channels = FIELD_PREP(NRFX_TDM_RX_CHANNELS_MASK, BIT_MASK(TDM_RX_CH_CNT)) | FIELD_PREP(NRFX_TDM_TX_CHANNELS_MASK, BIT_MASK(TDM_TX_CH_CNT)),
105+
.num_of_channels = CONCAT(NRF_TDM_CHANNELS_COUNT_, TDM_CH_CNT),
83106
.mck_setup = 0,
84-
.sck_setup = SCK_VALUE,
85-
.sck_polarity = NRF_TDM_POLARITY_POSEDGE,
86-
.fsync_polarity = NRF_TDM_POLARITY_NEGEDGE,
87-
.fsync_duration = NRF_TDM_FSYNC_DURATION_CHANNEL,
107+
.sck_setup = SCK_DIV_VALUE,
108+
// Set PCM long format
109+
.alignment = NRF_TDM_ALIGN_LEFT,
110+
.fsync_polarity = NRF_TDM_POLARITY_POSEDGE,
111+
.sck_polarity = NRF_TDM_POLARITY_NEGEDGE,
112+
.fsync_duration = NRF_TDM_FSYNC_DURATION_SCK,
113+
.channel_delay = NRF_TDM_CHANNEL_DELAY_NONE,
88114
};
89115

90116
static const nrf_tdm_pins_t m_pins = {
@@ -128,8 +154,10 @@ K_MEM_SLAB_DEFINE_STATIC(iso_out_slab,
128154
ROUND_UP((SAMPLES_NUM + 1) * ISO_OUT_CH_CNT * sizeof(sample_t), BUF_ALIGN),
129155
BUF_COUNT, BUF_ALIGN);
130156

131-
/* Buffers for TDM, 2 for each direction. */
132-
static sample_t tdm_buffers[4][TDM_RX_CH_CNT * (SAMPLES_NUM + 1)]
157+
static sample_t tdm_tx_buffers[2][TDM_TX_CH_CNT * (SAMPLES_NUM + 1)]
158+
__aligned(sizeof(uint32_t)) DMM_MEMORY_SECTION(DT_NODELABEL(tdm130));
159+
160+
static sample_t tdm_rx_buffers[2][TDM_RX_CH_CNT * (SAMPLES_NUM + 1)]
133161
__aligned(sizeof(uint32_t)) DMM_MEMORY_SECTION(DT_NODELABEL(tdm130));
134162

135163
struct tdm_data {
@@ -263,6 +291,7 @@ static void tdm_init(void)
263291

264292
nrf_gpio_cfg(NRF_GPIO_PIN_MAP(1,3), NRF_GPIO_PIN_DIR_OUTPUT, NRF_GPIO_PIN_INPUT_DISCONNECT,
265293
NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_S0S1, NRF_GPIO_PIN_NOSENSE);
294+
nrf_gpio_pin_clock_set(NRF_GPIO_PIN_MAP(1,3), true);
266295
nrf_gpio_cfg(NRF_GPIO_PIN_MAP(1,6), NRF_GPIO_PIN_DIR_OUTPUT, NRF_GPIO_PIN_INPUT_DISCONNECT,
267296
NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_S0S1, NRF_GPIO_PIN_NOSENSE);
268297
nrf_gpio_cfg(NRF_GPIO_PIN_MAP(1,4), NRF_GPIO_PIN_DIR_OUTPUT, NRF_GPIO_PIN_INPUT_DISCONNECT,
@@ -288,18 +317,28 @@ static void context_init(void)
288317
}
289318

290319
/* Initialize context with buffers from RAM3x space. */
291-
context.tdm_tx.buf[0] = tdm_buffers[0];
292-
context.tdm_tx.buf[1] = tdm_buffers[1];
293-
context.tdm_rx.buf[0] = tdm_buffers[2];
294-
context.tdm_rx.buf[1] = tdm_buffers[3];
320+
context.tdm_tx.buf[0] = tdm_tx_buffers[0];
321+
context.tdm_tx.buf[1] = tdm_tx_buffers[1];
322+
context.tdm_rx.buf[0] = tdm_rx_buffers[0];
323+
context.tdm_rx.buf[1] = tdm_rx_buffers[1];
295324
}
296325

297-
static uint32_t tdm_get_len(struct tdm_data *data, struct tdm_data *propagate)
326+
static uint32_t tdm_get_len(struct tdm_data *data, struct tdm_data *propagate, tdm_dir_t dir)
298327
{
299328
uint32_t len;
329+
uint32_t num_of_channels;
330+
331+
if (dir == tdm_rx) {
332+
num_of_channels = TDM_RX_CH_CNT;
333+
} else if (dir == tdm_tx) {
334+
num_of_channels = TDM_TX_CH_CNT;
335+
} else {
336+
LOG_ERR("invalid dir value");
337+
return 0;
338+
}
300339

301340
if (data->len_offset == 0) {
302-
return (SAMPLES_NUM * sizeof(sample_t) * TDM_RX_CH_CNT) / sizeof(uint32_t);
341+
return (SAMPLES_NUM * sizeof(sample_t) * num_of_channels) / sizeof(uint32_t);
303342
}
304343

305344
len = SAMPLES_NUM + data->len_offset;
@@ -308,7 +347,7 @@ static uint32_t tdm_get_len(struct tdm_data *data, struct tdm_data *propagate)
308347
}
309348
data->len_offset = 0;
310349

311-
return (len * sizeof(sample_t) * TDM_RX_CH_CNT) / sizeof(uint32_t);
350+
return (len * sizeof(sample_t) * num_of_channels) / sizeof(uint32_t);
312351
}
313352

314353
static void tdm_set_rx_ptr(bool first)
@@ -317,14 +356,14 @@ static void tdm_set_rx_ptr(bool first)
317356
int ret;
318357

319358
if (!first) {
320-
ret = ringbuf_put(&context.to_usb, buf, context.tdm_rx.len[context.tdm_rx.idx]);
359+
ret = ringbuf_put(&context.to_usb, buf, context.tdm_rx.len[context.tdm_rx.idx] / sizeof(sample_t));
321360
if (ret < 0) {
322361
LOG_WRN("No room in ring buffer for TDM data.");
323362
}
324363
}
325364

326-
context.tdm_rx.len[context.tdm_rx.idx] = tdm_get_len(&context.tdm_rx, NULL);
327-
nrf_tdm_rx_count_set(NRF_TDM130, context.tdm_rx.len[context.tdm_rx.idx]);
365+
context.tdm_rx.len[context.tdm_rx.idx] = tdm_get_len(&context.tdm_rx, NULL, tdm_rx);
366+
nrf_tdm_rx_count_set(NRF_TDM130, TDM_GET_MAX_LEN(context.tdm_rx.len[context.tdm_rx.idx], TDM_RX_CH_CNT));
328367
nrf_tdm_rx_buffer_set(NRF_TDM130, (uint32_t *)buf);
329368

330369
context.tdm_rx.idx = (context.tdm_rx.idx + 1) & 0x1;
@@ -337,19 +376,19 @@ static void tdm_set_tx_ptr(void)
337376
int ret;
338377

339378
/* Length correction propagates from TDM TX to TDM RX. */
340-
len = tdm_get_len(&context.tdm_tx, &context.tdm_rx);
341-
ret = ringbuf_get(&context.from_usb, tx_buf, len);
379+
len = tdm_get_len(&context.tdm_tx, &context.tdm_rx, tdm_tx);
380+
ret = ringbuf_get(&context.from_usb, tx_buf, len / sizeof(sample_t));
342381
if (ret < 0) {
343382
memset(tx_buf, 0, len * sizeof(uint32_t));
344383
LOG_WRN("No TDM data to send.");
345384
}
346385

347386
context.tdm_tx.idx = (context.tdm_tx.idx + 1) & 0x1;
348-
nrf_tdm_tx_count_set(NRF_TDM130, len);
387+
nrf_tdm_tx_count_set(NRF_TDM130, TDM_GET_MAX_LEN(len, TDM_TX_CH_CNT));
349388
nrf_tdm_tx_buffer_set(NRF_TDM130, (uint32_t *)tx_buf);
350389
}
351390

352-
static void tdm_start(buf_t * p_in, buf_t * p_out)
391+
static void tdm_start(void)
353392
{
354393
nrf_tdm_enable(NRF_TDM130);
355394
nrf_tdm_configure(NRF_TDM130, &m_cfg);
@@ -567,7 +606,7 @@ int main(void)
567606
DBG_PIN_INIT(3);
568607

569608
LOG_INF("FLPR started");
570-
609+
//LOG_ERR("sample_width = %u channels = %x num_of_channels = %u", m_cfg.sample_width, m_cfg.channels, m_cfg.num_of_channels);
571610
while (1 || rpt) {
572611
if (usb_sof_changed())
573612
{
@@ -612,7 +651,7 @@ int main(void)
612651
DBG_PIN_SET(3);
613652
context_init();
614653
/*tdm_start(&m_iso_in_buffers[0], &m_iso_out_buffers[0]);*/
615-
tdm_start(&m_iso_in_buffers[0], &m_iso_out_buffers[0]);
654+
tdm_start();
616655
feedback_start(mp_fbck, m_tdm_counter, true);
617656
m_tdm_started = true;
618657
DBG_PIN_CLR(3);

0 commit comments

Comments
 (0)