Skip to content

Commit 7713369

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 7713369

File tree

1 file changed

+70
-33
lines changed
  • samples/subsys/usb/uac2_implicit_feedback/flpr/src

1 file changed

+70
-33
lines changed

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

Lines changed: 70 additions & 33 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+
/* buffers configuration */
13+
#define ISO_IN_CH_CNT 4
14+
#define ISO_OUT_CH_CNT 4
15+
#define TDM_WORD_SIZE 32
1216

13-
#define ISO_IN_CH_CNT 1
14-
#define TDM_RX_CH_CNT 2
15-
16-
#define ISO_OUT_CH_CNT 2
17-
#define TDM_TX_CH_CNT 2
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

@@ -40,7 +45,16 @@ LOG_MODULE_REGISTER(main, 1);
4045

4146
static struct feedback_ctx * mp_fbck;
4247

48+
typedef enum {
49+
tdm_tx,
50+
tdm_rx
51+
} tdm_dir_t;
52+
53+
#if TDM_WORD_SIZE > 16
54+
typedef uint32_t sample_t;
55+
#else
4356
typedef uint16_t sample_t;
57+
#endif
4458

4559
typedef struct {
4660
void * ptr;
@@ -57,6 +71,15 @@ static uint8_t m_iso_out_idx;
5771
/*static uint32_t m_fake_sample_tx[SAMPLES_NUM + 1] __aligned(4);*/
5872
/*static uint32_t m_fake_sample_rx[SAMPLES_NUM + 1] __aligned(4);*/
5973

74+
#define NRFX_TDM_NUM_OF_CHANNELS (TDM_CONFIG_CHANNEL_NUM_NUM_Max + 1)
75+
76+
#define NRFX_TDM_TX_CHANNELS_MASK \
77+
GENMASK(TDM_CONFIG_CHANNEL_MASK_Tx0Enable_Pos + TDM_CONFIG_CHANNEL_NUM_NUM_Max, \
78+
TDM_CONFIG_CHANNEL_MASK_Tx0Enable_Pos)
79+
#define NRFX_TDM_RX_CHANNELS_MASK \
80+
GENMASK(TDM_CONFIG_CHANNEL_MASK_Rx0Enable_Pos + TDM_CONFIG_CHANNEL_NUM_NUM_Max, \
81+
TDM_CONFIG_CHANNEL_MASK_Rx0Enable_Pos)
82+
6083
static void buffers_flush(void)
6184
{
6285
m_iso_in_idx = 0;
@@ -68,23 +91,24 @@ static void buffers_flush(void)
6891
/* === TDM === */
6992
#define MCKCONST 1048576UL
7093
#define AUDIOPLL_FREQ 12287963UL
71-
#define WORD_SIZE 16UL
94+
#define WORD_SIZE CONCAT(TDM_WORD_SIZE, UL)
7295
#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))
96+
#define SCK_FREQ WORD_SIZE * FRAME_CLK_FREQ * TDM_CH_CNT
97+
#define SCK_DIV_VALUE ((uint32_t)(((uint64_t)SCK_FREQ * MCKCONST) / (AUDIOPLL_FREQ + (SCK_FREQ / 2) )* 4096))
7598

7699
static const nrf_tdm_config_t m_cfg = {
77100
.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,
101+
.sample_width = CONCAT(NRF_TDM_SWIDTH_, TDM_WORD_SIZE, BIT),
102+
.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)),
103+
.num_of_channels = CONCAT(NRF_TDM_CHANNELS_COUNT_, TDM_CH_CNT),
83104
.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,
105+
.sck_setup = SCK_DIV_VALUE,
106+
// Set PCM long format
107+
.alignment = NRF_TDM_ALIGN_LEFT,
108+
.fsync_polarity = NRF_TDM_POLARITY_POSEDGE,
109+
.sck_polarity = NRF_TDM_POLARITY_NEGEDGE,
110+
.fsync_duration = NRF_TDM_FSYNC_DURATION_SCK,
111+
.channel_delay = NRF_TDM_CHANNEL_DELAY_NONE,
88112
};
89113

90114
static const nrf_tdm_pins_t m_pins = {
@@ -128,8 +152,10 @@ K_MEM_SLAB_DEFINE_STATIC(iso_out_slab,
128152
ROUND_UP((SAMPLES_NUM + 1) * ISO_OUT_CH_CNT * sizeof(sample_t), BUF_ALIGN),
129153
BUF_COUNT, BUF_ALIGN);
130154

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

135161
struct tdm_data {
@@ -263,6 +289,7 @@ static void tdm_init(void)
263289

264290
nrf_gpio_cfg(NRF_GPIO_PIN_MAP(1,3), NRF_GPIO_PIN_DIR_OUTPUT, NRF_GPIO_PIN_INPUT_DISCONNECT,
265291
NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_S0S1, NRF_GPIO_PIN_NOSENSE);
292+
nrf_gpio_pin_clock_set(NRF_GPIO_PIN_MAP(1,3), true);
266293
nrf_gpio_cfg(NRF_GPIO_PIN_MAP(1,6), NRF_GPIO_PIN_DIR_OUTPUT, NRF_GPIO_PIN_INPUT_DISCONNECT,
267294
NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_S0S1, NRF_GPIO_PIN_NOSENSE);
268295
nrf_gpio_cfg(NRF_GPIO_PIN_MAP(1,4), NRF_GPIO_PIN_DIR_OUTPUT, NRF_GPIO_PIN_INPUT_DISCONNECT,
@@ -288,18 +315,28 @@ static void context_init(void)
288315
}
289316

290317
/* 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];
318+
context.tdm_tx.buf[0] = tdm_tx_buffers[0];
319+
context.tdm_tx.buf[1] = tdm_tx_buffers[1];
320+
context.tdm_rx.buf[0] = tdm_rx_buffers[0];
321+
context.tdm_rx.buf[1] = tdm_rx_buffers[1];
295322
}
296323

297-
static uint32_t tdm_get_len(struct tdm_data *data, struct tdm_data *propagate)
324+
static uint32_t tdm_get_len(struct tdm_data *data, struct tdm_data *propagate, tdm_dir_t dir)
298325
{
299326
uint32_t len;
327+
uint32_t num_of_channels;
328+
329+
if (dir == tdm_rx) {
330+
num_of_channels = TDM_RX_CH_CNT;
331+
} else if (dir == tdm_tx) {
332+
num_of_channels = TDM_TX_CH_CNT;
333+
} else {
334+
LOG_ERR("invalid dir value");
335+
return 0;
336+
}
300337

301338
if (data->len_offset == 0) {
302-
return (SAMPLES_NUM * sizeof(sample_t) * TDM_RX_CH_CNT) / sizeof(uint32_t);
339+
return (SAMPLES_NUM * sizeof(sample_t) * num_of_channels) / sizeof(uint32_t);
303340
}
304341

305342
len = SAMPLES_NUM + data->len_offset;
@@ -308,7 +345,7 @@ static uint32_t tdm_get_len(struct tdm_data *data, struct tdm_data *propagate)
308345
}
309346
data->len_offset = 0;
310347

311-
return (len * sizeof(sample_t) * TDM_RX_CH_CNT) / sizeof(uint32_t);
348+
return (len * sizeof(sample_t) * num_of_channels) / sizeof(uint32_t);
312349
}
313350

314351
static void tdm_set_rx_ptr(bool first)
@@ -317,13 +354,13 @@ static void tdm_set_rx_ptr(bool first)
317354
int ret;
318355

319356
if (!first) {
320-
ret = ringbuf_put(&context.to_usb, buf, context.tdm_rx.len[context.tdm_rx.idx]);
357+
ret = ringbuf_put(&context.to_usb, buf, context.tdm_rx.len[context.tdm_rx.idx] / sizeof(sample_t));
321358
if (ret < 0) {
322359
LOG_WRN("No room in ring buffer for TDM data.");
323360
}
324361
}
325362

326-
context.tdm_rx.len[context.tdm_rx.idx] = tdm_get_len(&context.tdm_rx, NULL);
363+
context.tdm_rx.len[context.tdm_rx.idx] = tdm_get_len(&context.tdm_rx, NULL, tdm_rx);
327364
nrf_tdm_rx_count_set(NRF_TDM130, context.tdm_rx.len[context.tdm_rx.idx]);
328365
nrf_tdm_rx_buffer_set(NRF_TDM130, (uint32_t *)buf);
329366

@@ -337,8 +374,8 @@ static void tdm_set_tx_ptr(void)
337374
int ret;
338375

339376
/* 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);
377+
len = tdm_get_len(&context.tdm_tx, &context.tdm_rx, tdm_tx);
378+
ret = ringbuf_get(&context.from_usb, tx_buf, len / sizeof(sample_t));
342379
if (ret < 0) {
343380
memset(tx_buf, 0, len * sizeof(uint32_t));
344381
LOG_WRN("No TDM data to send.");
@@ -349,7 +386,7 @@ static void tdm_set_tx_ptr(void)
349386
nrf_tdm_tx_buffer_set(NRF_TDM130, (uint32_t *)tx_buf);
350387
}
351388

352-
static void tdm_start(buf_t * p_in, buf_t * p_out)
389+
static void tdm_start(void)
353390
{
354391
nrf_tdm_enable(NRF_TDM130);
355392
nrf_tdm_configure(NRF_TDM130, &m_cfg);
@@ -612,7 +649,7 @@ int main(void)
612649
DBG_PIN_SET(3);
613650
context_init();
614651
/*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]);
652+
tdm_start();
616653
feedback_start(mp_fbck, m_tdm_counter, true);
617654
m_tdm_started = true;
618655
DBG_PIN_CLR(3);

0 commit comments

Comments
 (0)