99#include <zephyr/logging/log.h>
1010LOG_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
4146static 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
4356typedef uint16_t sample_t ;
57+ #endif
4458
4559typedef 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+
6083static 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
7699static 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
90114static 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
135161struct 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
314351static 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