99#include <zephyr/logging/log.h>
1010LOG_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+
4148static 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
4358typedef uint16_t sample_t ;
59+ #endif
4460
4561typedef 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+
6085static 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
76101static 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
90116static 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
135163struct 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
314353static 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