I2S mic to USB audio (nRF5 SDK v17.0.2)

Hello,

nRF5 SDK v17.0.2, Keil5

USB audio demo and I2S demo,

i2s cannect two mic(L and R),  16bit 48K STEREO,

how to put i2s data to usb audio?

i add function to USB audio demo as follow:

uint16_t usb_put_data(const uint16_t* p_buff, uint16_t size)
{
 	ret_code_t ret = app_usbd_audio_class_tx_start(&m_app_audio_microphone.base, p_buff, size*2);
 	if (NRF_SUCCESS == ret)
	{
		//bsp_board_led_invert(LED_AUDIO_RX);
	}
	return size;
}

don't know if it sucess, so some audio data lost.

it note This function should be called in reaction to a SOF event.

where the SOF?

int hp_sof_ev_handler(uint16_t framecnt)

or 

usbd_user_ev_handler(app_usbd_event_type_t event)  ---> case APP_USBD_EVT_DRV_SOF:

   How to do it specifically?

      

Best regards

Parents
  • Hi,

    I assume you have taken a look at how it's done in the usbd_audio example.

    In the usbd_user_ev_handler, you get the event APP_USBD_EVT_DRV_SOF. Here app_usbd_audio_class_rx_start() is called, and when that is completed, you get the APP_USBD_AUDIO_USER_EVT_RX_DONE in hp_audio_user_ev_handler(), and here app_usbd_audio_class_tx_start() is called. In that way, it's called in a reaction to a SOF event, in the usbd_audio example.

  • Hi, thanks for reply,

    app_usbd_audio_class_rx_start()  and APP_USBD_AUDIO_USER_EVT_RX_DONE 

    is recv from PC,then loop back to PC,

    i don't need it, my project only recv from I2S and then put the audio data to PC by usb audio.

    I2S demo,data_handler()-->check_rx_data(),got audio data,how to put to usb audio?

    1.Using app_usbd_audio_class_tx_start() directly,  i suspect losing some data frames.

    2.put data to a memery buffer first, then where to call app_usbd_audio_class_tx_start()?

    if call it once in first put to buffer,and then call in APP_USBD_AUDIO_USER_EVT_TX_DONE,

    will lost most of audio data.

            

    Best regards

Reply
  • Hi, thanks for reply,

    app_usbd_audio_class_rx_start()  and APP_USBD_AUDIO_USER_EVT_RX_DONE 

    is recv from PC,then loop back to PC,

    i don't need it, my project only recv from I2S and then put the audio data to PC by usb audio.

    I2S demo,data_handler()-->check_rx_data(),got audio data,how to put to usb audio?

    1.Using app_usbd_audio_class_tx_start() directly,  i suspect losing some data frames.

    2.put data to a memery buffer first, then where to call app_usbd_audio_class_tx_start()?

    if call it once in first put to buffer,and then call in APP_USBD_AUDIO_USER_EVT_TX_DONE,

    will lost most of audio data.

            

    Best regards

Children
  • Hi,

    Try calling it in the usbd_user_ev_handler() when you get the event APP_USBD_EVT_DRV_SOF . Also remember to check the return code from app_usbd_audio_class_tx_start() if you are suspecting you are losing data.

  • Hi,  thanks for reply

    i'v try,but it never to be called.  see code

     

    #include <stdint.h>
    #include <stdbool.h>
    #include <stddef.h>
    
    #include "nrf.h"
    #include "app_util.h"
    #include "nrf_drv_usbd.h"
    #include "nrf_drv_clock.h"
    #include "nrf_gpio.h"
    #include "nrf_delay.h"
    #include "nrf_drv_power.h"
    
    #include "app_usbd.h"
    #include "app_usbd_core.h"
    #include "app_usbd_string_desc.h"
    #include "app_usbd_audio.h"
    #include "app_error.h"
    #include "boards.h"
    #include "i2s_audio.h"
    
    
    #include "nrf_log.h"
    #include "nrf_log_ctrl.h"
    #include "nrf_log_default_backends.h"
    
    static bool nLoop=false;
    //#define LED_USB_RESUME (BSP_BOARD_LED_0)
    //#define LED_USB_START  (BSP_BOARD_LED_1)
    //#define LED_AUDIO_RX   (BSP_BOARD_LED_2)
    //#define LED_AUDIO_TX   (BSP_BOARD_LED_3)
    
    /**
     * @brief USB audio samples size
     */
    #define BUFFER_SIZE  (48)
    
    /**
     * @brief Enable power USB detection
     *
     * Configure if example supports USB port connection
     */
    #ifndef USBD_POWER_DETECTION
    #define USBD_POWER_DETECTION true
    #endif
    
    /**
     * @brief Audio class user event handler
     */
    static void hp_audio_user_ev_handler(app_usbd_class_inst_t const * p_inst, app_usbd_audio_user_event_t   event);
    static void mic_audio_user_ev_handler(app_usbd_class_inst_t const * p_inst, app_usbd_audio_user_event_t   event);
    
    /* Channels and feature controls configuration */
    
    /**
     * @brief   Input terminal channel configuration
     */
    #define HP_TERMINAL_CH_CONFIG()                                                                       \
            (APP_USBD_AUDIO_IN_TERM_CH_CONFIG_LEFT_FRONT | APP_USBD_AUDIO_IN_TERM_CH_CONFIG_RIGHT_FRONT)
    
    /**
     * @brief   Feature controls
     *
     *      general
     *      channel 0
     *      channel 1
     */
    #define HP_FEATURE_CONTROLS()                                               \
            APP_USBD_U16_TO_RAW_DSC(APP_USBD_AUDIO_FEATURE_UNIT_CONTROL_MUTE),  \
            APP_USBD_U16_TO_RAW_DSC(APP_USBD_AUDIO_FEATURE_UNIT_CONTROL_MUTE),  \
            APP_USBD_U16_TO_RAW_DSC(APP_USBD_AUDIO_FEATURE_UNIT_CONTROL_MUTE)
    
    
    
    /**
     * @brief   Input terminal channel configuration
     */
    #define MIC_TERMINAL_CH_CONFIG()                                                                       \
            (APP_USBD_AUDIO_IN_TERM_CH_CONFIG_LEFT_FRONT | APP_USBD_AUDIO_IN_TERM_CH_CONFIG_RIGHT_FRONT)
    
    /**
     * @brief   Feature controls
     *
     *      general
     *      channel 0
     *      channel 1
     */
    #define MIC_FEATURE_CONTROLS()                                                                     \
            APP_USBD_U16_TO_RAW_DSC(APP_USBD_AUDIO_FEATURE_UNIT_CONTROL_MUTE),                         \
            APP_USBD_U16_TO_RAW_DSC(APP_USBD_AUDIO_FEATURE_UNIT_CONTROL_MUTE),                         \
            APP_USBD_U16_TO_RAW_DSC(APP_USBD_AUDIO_FEATURE_UNIT_CONTROL_MUTE)
    
    
    /* Microphone descriptors */
    
    /**
     * @brief   Audio class specific format descriptor
     */
    APP_USBD_AUDIO_FORMAT_DESCRIPTOR(m_mic_form_desc, 
                                     APP_USBD_AUDIO_AS_FORMAT_I_DSC(    /* Format type 1 descriptor */
                                        2,                  						/* Number of channels */
                                        2,                              /* Subframe size */
                                        16,                             /* Bit resolution */
                                        1,                              /* Frequency type */
                                        APP_USBD_U24_TO_RAW_DSC(48000)) /* Frequency */
                                    );
    
    /**
     * @brief   Audio class input terminal descriptor
     */
    APP_USBD_AUDIO_INPUT_DESCRIPTOR(m_mic_inp_desc, 
                                    APP_USBD_AUDIO_INPUT_TERMINAL_DSC(
                                        1,                                     /* Terminal ID */
                                        APP_USBD_AUDIO_TERMINAL_IN_MICROPHONE, /* Terminal type */
                                        2,                         						 /* Number of channels */
                                        MIC_TERMINAL_CH_CONFIG())              /* Channels config */
                                    );
    
    /**
     * @brief   Audio class output terminal descriptor
     */
    APP_USBD_AUDIO_OUTPUT_DESCRIPTOR(m_mic_out_desc, 
                                     APP_USBD_AUDIO_OUTPUT_TERMINAL_DSC(
                                        3,                                     /* Terminal ID */
                                        APP_USBD_AUDIO_TERMINAL_USB_STREAMING, /* Terminal type */
                                        2)                                     /* Source ID */
                                    );
    
    /**
     * @brief   Audio class feature unit descriptor
     */
    APP_USBD_AUDIO_FEATURE_DESCRIPTOR(m_mic_fea_desc, 
                                      APP_USBD_AUDIO_FEATURE_UNIT_DSC(
                                        2,                      /* Unit ID */
                                        1,                      /* Source ID */
                                        MIC_FEATURE_CONTROLS()) /* List of controls */
                                     );
    
    /* Headphones descriptors */
    
    /**
     * @brief   Audio class specific format III descriptor
     */
    APP_USBD_AUDIO_FORMAT_DESCRIPTOR(m_hp_form_desc, 
                                     APP_USBD_AUDIO_AS_FORMAT_III_DSC(    /* Format type 3 descriptor */
                                        2,                                /* Number of channels */
                                        2,                                /* Subframe size */
                                        16,                               /* Bit resolution */
                                        1,                                /* Frequency type */
                                        APP_USBD_U24_TO_RAW_DSC(48000))   /* Frequency */
                                    );
    
    /**
     * @brief   Audio class input terminal descriptor
     */
    APP_USBD_AUDIO_INPUT_DESCRIPTOR(m_hp_inp_desc, 
                                    APP_USBD_AUDIO_INPUT_TERMINAL_DSC(
                                        1,                                     /* Terminal ID */
                                        APP_USBD_AUDIO_TERMINAL_USB_STREAMING, /* Terminal type */
                                        2,                         						 /* Number of channels */
                                        HP_TERMINAL_CH_CONFIG())               /* Channels config */
                                   );
    
    /**
     * @brief   Audio class output terminal descriptor
     */
    APP_USBD_AUDIO_OUTPUT_DESCRIPTOR(m_hp_out_desc, 
                                     APP_USBD_AUDIO_OUTPUT_TERMINAL_DSC(
                                        3,                                      /* Terminal ID */
                                        APP_USBD_AUDIO_TERMINAL_OUT_HEADPHONES, /* Terminal type */
                                        2)                                      /* Source ID */
                                    );
    
    /**
     * @brief   Audio class feature unit descriptor
     */
    APP_USBD_AUDIO_FEATURE_DESCRIPTOR(m_hp_fea_desc, 
                                      APP_USBD_AUDIO_FEATURE_UNIT_DSC(
                                        2,                     /* Unit ID */
                                        1,                     /* Source ID */
                                        HP_FEATURE_CONTROLS()) /* List of controls */
                                     );
    
    /* Interfaces lists */
    
    /**
     * @brief Interfaces list passed to @ref APP_USBD_AUDIO_GLOBAL_DEF
     */
    #define HP_INTERFACES_CONFIG() APP_USBD_AUDIO_CONFIG_OUT(0, 1)
    
    /**
     * @brief Interfaces list passed to @ref APP_USBD_AUDIO_GLOBAL_DEF
     */
    #define MIC_INTERFACES_CONFIG() APP_USBD_AUDIO_CONFIG_IN(2, 3)
    
    /*lint -save -e26 -e64 -e123 -e505 -e651*/
    
    
    /**
     * @brief Headphone Audio class instance
     */
    APP_USBD_AUDIO_GLOBAL_DEF(m_app_audio_headphone,
                              HP_INTERFACES_CONFIG(),
                              hp_audio_user_ev_handler,
                              &m_hp_form_desc,
                              &m_hp_inp_desc,
                              &m_hp_out_desc,
                              &m_hp_fea_desc,
                              0,
                              APP_USBD_AUDIO_AS_IFACE_FORMAT_PCM,
                              192,
                              APP_USBD_AUDIO_SUBCLASS_AUDIOSTREAMING,
                              1
    );
    
    
    
    /**
     * @brief Microphone Audio class instance
     */
    APP_USBD_AUDIO_GLOBAL_DEF(m_app_audio_microphone,
                              MIC_INTERFACES_CONFIG(),
                              mic_audio_user_ev_handler,
                              &m_mic_form_desc,
                              &m_mic_inp_desc,
                              &m_mic_out_desc,
                              &m_mic_fea_desc,
                              0,
                              APP_USBD_AUDIO_AS_IFACE_FORMAT_PCM,
                              192,
                              APP_USBD_AUDIO_SUBCLASS_AUDIOSTREAMING,
                              3
    );
    
    
    /*lint -restore*/
    
    /**
     * @brief Internal audio temporary buffer
     */
    static int16_t  m_temp_buffer[2 * BUFFER_SIZE];
    static int err_count=0,tx_count=0,tx_done=0;
    
    #define BUFFER_TX_SIZE  (1024)
    static int16_t  m_tx_buffer[BUFFER_TX_SIZE];
    static int16_t  m_tx_start_idx=0,m_tx_deal_idx=0;
    static int havedata=0, dealdata=0;
    
    /**
     * @brief The size of last received block from the microphone
     */
    static size_t m_temp_buffer_size;
    
    /**
     * @brief Actual headphones mute
     */
    static uint8_t  m_mute_hp;
    
    /**
     * @brief Actual sampling frequency
     */
    static uint32_t m_freq_hp;
    
    /**
     * @brief Actual microphone mute state
     */
    static uint8_t  m_mute_mic;
    
    /**
     * @brief Actual microphone sampling frequency
     */
    static uint32_t m_freq_mic;
    
    /**
     * @brief Audio class specific request handle (headphones)
     */
    static void hp_audio_user_class_req(app_usbd_class_inst_t const * p_inst)
    {
        app_usbd_audio_t const * p_audio = app_usbd_audio_class_get(p_inst);
        app_usbd_audio_req_t * p_req = app_usbd_audio_class_request_get(p_audio);
    
        UNUSED_VARIABLE(m_mute_hp);
        UNUSED_VARIABLE(m_freq_hp);
    
        switch (p_req->req_target)
        {
            case APP_USBD_AUDIO_CLASS_REQ_IN:
    
                if (p_req->req_type == APP_USBD_AUDIO_REQ_SET_CUR)
                {
                    //Only mute control is defined
                    p_req->payload[0] = m_mute_hp;
                }
    
                break;
            case APP_USBD_AUDIO_CLASS_REQ_OUT:
    
                if (p_req->req_type == APP_USBD_AUDIO_REQ_SET_CUR)
                {
                    //Only mute control is defined
                    m_mute_hp = p_req->payload[0];
                }
    
                break;
            case APP_USBD_AUDIO_EP_REQ_IN:
                break;
            case APP_USBD_AUDIO_EP_REQ_OUT:
    
                if (p_req->req_type == APP_USBD_AUDIO_REQ_SET_CUR)
                {
                    //Only set frequency is supported
                    m_freq_hp = uint24_decode(p_req->payload);
                }
    
                break;
            default:
                break;
        }
    }
    
    /**
     * @brief Audio class specific request handle (microphone)
     */
    static void mic_audio_user_class_req(app_usbd_class_inst_t const * p_inst)
    {
        app_usbd_audio_t const * p_audio = app_usbd_audio_class_get(p_inst);
        app_usbd_audio_req_t * p_req = app_usbd_audio_class_request_get(p_audio);
    
        UNUSED_VARIABLE(m_mute_mic);
        UNUSED_VARIABLE(m_freq_mic);
    
        switch (p_req->req_target)
        {
            case APP_USBD_AUDIO_CLASS_REQ_IN:
    
                if (p_req->req_type == APP_USBD_AUDIO_REQ_SET_CUR)
                {
                    //Only mute control is defined
                    p_req->payload[0] = m_mute_mic;
                }
    
                break;
            case APP_USBD_AUDIO_CLASS_REQ_OUT:
    
                if (p_req->req_type == APP_USBD_AUDIO_REQ_SET_CUR)
                {
                    //Only mute control is defined
                    m_mute_mic = p_req->payload[0];
                }
    
                break;
            case APP_USBD_AUDIO_EP_REQ_IN:
                break;
            case APP_USBD_AUDIO_EP_REQ_OUT:
    
                if (p_req->req_type == APP_USBD_AUDIO_REQ_SET_CUR)
                {
                    //Only set frequency is supported
                    m_freq_mic = uint24_decode(p_req->payload);
                }
    
                break;
            default:
                break;
        }
    }
    
    /**
     * @brief User event handler @ref app_usbd_audio_user_ev_handler_t (headphones)
     */
    static void hp_audio_user_ev_handler(app_usbd_class_inst_t const * p_inst,app_usbd_audio_user_event_t   event)
    {
        app_usbd_audio_t const * p_audio = app_usbd_audio_class_get(p_inst);
        UNUSED_VARIABLE(p_audio);
        switch (event)
        {
            case APP_USBD_AUDIO_USER_EVT_CLASS_REQ:
                hp_audio_user_class_req(p_inst);
                break;
    				case APP_USBD_AUDIO_USER_EVT_RX_DONE:
            {
                /* Block from headphones copied into buffer, send it into microphone input */
                if(nLoop){
    							ret_code_t ret = app_usbd_audio_class_tx_start(&m_app_audio_microphone.base, m_temp_buffer, m_temp_buffer_size);
    							//if (NRF_SUCCESS == ret) bsp_board_led_invert(LED_AUDIO_RX);
    						}else{
    							uint16_t c = put_data(m_temp_buffer, m_temp_buffer_size);//I2S
    						}
                break;
            }
            break;
        }
    }
    /*
    	Call this in I2S check_rx_data(),16bit 48Khz STEREO, size=80
    */
    uint16_t usb_put_data(const uint16_t* p_buff, uint16_t size)
    {
    	for(int i=0;i<size;i++)
    	{
    		m_tx_buffer[m_tx_start_idx]=p_buff[i];
    		m_tx_start_idx%=BUFFER_TX_SIZE;
    	}
    	m_temp_buffer_size=size; havedata+=size;
    
    	//if(tx_done)return size;
    //	ret_code_t ret = app_usbd_audio_class_tx_start(&m_app_audio_microphone.base, p_buff, size*2);
    //	if (NRF_SUCCESS == ret)
    //	{
    //		//bsp_board_led_invert(LED_AUDIO_RX);
    //	}
    	return size;
    }
    
    /**
     * @brief User event handler @ref app_usbd_audio_user_ev_handler_t (microphone)
     */
    static void mic_audio_user_ev_handler(app_usbd_class_inst_t const * p_inst,app_usbd_audio_user_event_t   event)
    {
        app_usbd_audio_t const * p_audio = app_usbd_audio_class_get(p_inst);
        UNUSED_VARIABLE(p_audio);
    
        switch (event)
        {
            case APP_USBD_AUDIO_USER_EVT_CLASS_REQ:
                mic_audio_user_class_req(p_inst);
                break;
            case APP_USBD_AUDIO_USER_EVT_TX_DONE:
            {
                if(tx_count%500==1)
    							NRF_LOG_INFO("mic DOWN %d  %d  (have:%d - deal:%d = %d)\n",tx_count,tx_done,havedata,dealdata,havedata-dealdata);
    						tx_done++; dealdata+=m_temp_buffer_size;
    											
                //bsp_board_led_invert(LED_AUDIO_TX);
                break;
            }
            default:
                break;
        }
    }
    
    static void hp_sof_ev_handler(uint16_t framecnt)
    {
    		ret_code_t ret;
        UNUSED_VARIABLE(framecnt);
        if (APP_USBD_STATE_Configured != app_usbd_core_state_get())
        {
            return;
        }
    
        size_t rx_size = app_usbd_audio_class_rx_size_get(&m_app_audio_headphone.base);
        m_temp_buffer_size = rx_size;
        if (rx_size > 0)
        {
            ASSERT(rx_size <= sizeof(m_temp_buffer));
            ret = app_usbd_audio_class_rx_start(&m_app_audio_headphone.base, m_temp_buffer, rx_size);
            if (NRF_SUCCESS != ret)
            {
                NRF_LOG_ERROR("Cannot start RX transfer from headphone\n");
            }
        }
    }
    
    /**
     * @brief USBD library specific event handler.
     *
     * @param event     USBD library event.
     */
    static void usbd_user_ev_handler(app_usbd_event_type_t event)
    {
        switch (event)
        {
            case APP_USBD_EVT_DRV_SOF:
    					{
    							for(int i=0;i<m_temp_buffer_size;i++)
    							{
    								m_temp_buffer[i]=m_tx_buffer[m_tx_deal_idx];
    								m_tx_deal_idx%=BUFFER_TX_SIZE;
    							}
    							app_usbd_audio_class_tx_start(&m_app_audio_microphone.base, m_temp_buffer, m_temp_buffer_size*2);		
    					}
                //NRF_LOG_INFO("APP_USBD_EVT_DRV_SOF");
                break;
            case APP_USBD_EVT_DRV_SUSPEND:
                //bsp_board_leds_off();
                break;
            case APP_USBD_EVT_DRV_RESUME:
                //bsp_board_led_on(LED_USB_RESUME);
                break;
            case APP_USBD_EVT_STARTED:
                //bsp_board_led_on(LED_USB_START);
                break;
            case APP_USBD_EVT_STOPPED:
                app_usbd_disable();
                //bsp_board_leds_off();
                break;
            case APP_USBD_EVT_POWER_DETECTED:
                NRF_LOG_INFO("USB power detected");
    						
                if (!nrf_drv_usbd_is_enabled())
                {
                    app_usbd_enable();
                }
                break;
            case APP_USBD_EVT_POWER_REMOVED:
                NRF_LOG_INFO("USB power removed");
                app_usbd_stop();
                break;
            case APP_USBD_EVT_POWER_READY:
                NRF_LOG_INFO("USB ready");
                app_usbd_start();
                break;
            default:
                break;
        }
    }
    
    
    
    int main(void)
    {
        ret_code_t ret;
    		nLoop=loop;
        static const app_usbd_config_t usbd_config = {
            .ev_state_proc = usbd_user_ev_handler,
            .enable_sof = true
        };
    
        ret = NRF_LOG_INIT(NULL);
        APP_ERROR_CHECK(ret);
        NRF_LOG_DEFAULT_BACKENDS_INIT();
    
        ret = nrf_drv_clock_init();
        APP_ERROR_CHECK(ret);
    
        NRF_LOG_INFO("USBD audio init");NRF_LOG_FLUSH();
    
        // Initialize LEDs and buttons
        //bsp_board_init(BSP_INIT_LEDS | BSP_INIT_BUTTONS);
    
        ret = app_usbd_init(&usbd_config);
        APP_ERROR_CHECK(ret);
    
        app_usbd_class_inst_t const * class_inst_hp =
            app_usbd_audio_class_inst_get(&m_app_audio_headphone);
    
        ret = app_usbd_audio_sof_interrupt_register(class_inst_hp, hp_sof_ev_handler);
        APP_ERROR_CHECK(ret);
    
        ret = app_usbd_class_append(class_inst_hp);
        APP_ERROR_CHECK(ret);
    
        app_usbd_class_inst_t const * class_inst_mic =
            app_usbd_audio_class_inst_get(&m_app_audio_microphone);
        ret = app_usbd_class_append(class_inst_mic);
        APP_ERROR_CHECK(ret);
        
        if (USBD_POWER_DETECTION)
        {
            ret = app_usbd_power_events_enable();
            APP_ERROR_CHECK(ret);
        }
        else
        {
            NRF_LOG_INFO("No USB power detection enabled\r\nStarting USB now");NRF_LOG_FLUSH();
    
            app_usbd_enable();
            app_usbd_start();
        }
        NRF_LOG_INFO("USBD audio started");NRF_LOG_FLUSH();
    		//bsp_board_leds_on();//test
        //NRF_LOG_INFO("USBD audio will loop");
    		i2s_audio_init();
    
        while (true)
        {
            while (app_usbd_event_queue_process())//must loop call this, if not non device in PC
            {
                /* Nothing to do */
            }
    
            UNUSED_RETURN_VALUE(NRF_LOG_PROCESS());
            /* Sleep CPU only if there was no interrupt since last loop processing */
            __WFE();
        }
    		return 0;
    }
    
    void usb_audio_uninit()
    {
    	app_usbd_stop();
    	app_usbd_disable();
    	app_usbd_uninit();
    }
    
    

    #include <stdio.h>
    #include "nrf_drv_i2s.h"
    #include "nrf_delay.h"
    #include "app_util_platform.h"
    #include "app_error.h"
    #include "boards.h"
    #include "nrf_queue.h"
    #include "nrf_log.h"
    #include "nrf_log_ctrl.h"
    #include "nrf_log_default_backends.h"
    
    #include "nrfx_i2s.h"
    #include "i2s_audio.h"
    #include "usbd_audio.h"
    
    #define I2S_SCK_PIN 		0x07
    #define I2S_LRCK_PIN 		0x08
    #define I2S_SDOUT_PIN 	0xff
    #define I2S_SDIN_PIN 		0x28
    
    
    #define I2S_DATA_BLOCK_WORDS 40
    
    static uint32_t m_buffer_rx32u[3][I2S_DATA_BLOCK_WORDS];
    static nrfx_i2s_buffers_t initial_buffers[3];
    static int _tx_data_idx=0,_rx_data_idx=0;
    static uint32_t* volatile mp_block_to_fill  = NULL;
    static uint32_t const * volatile mp_block_to_check = NULL;
    static nrfx_i2s_buffers_t* volatile current_buffer=NULL;
    
    
    static uint16_t 	mic_data[I2S_DATA_BLOCK_WORDS*2];
    static int 	 			mic_enc_idx=0,discard=0;
    //------------------------------------------------------------------------------------
    //------------------------------------------------------------------------------------
    static void check_rx_data(uint32_t const * p_block)
    {
    	bool slog=(rand()%9000==9);
    	mic_enc_idx=0;
    	// [each data word contains two 16-bit samples]
    	for (int i = 0; i < I2S_DATA_BLOCK_WORDS; i++)//from mic
    	{
    		uint32_t const * p_word = &p_block[i];
    		uint16_t actual_sample_l = ((uint16_t const *)p_word)[0];//
    		uint16_t actual_sample_r = ((uint16_t const *)p_word)[1];//
    		mic_data[mic_enc_idx++]=actual_sample_l;
    		mic_data[mic_enc_idx++]=actual_sample_r;
    	}
    	if(slog)NRF_LOG_INFO("Mic:  %02x  %02x  %02x  %02x  %02x  %02x\n",mic_data[0]&0Xffff,mic_data[1]&0Xffff,mic_data[2]&0Xffff,mic_data[3]&0Xffff,mic_data[4]&0Xffff,mic_data[5]&0Xffff);
    	uint16_t c =  usb_put_data(mic_data, I2S_DATA_BLOCK_WORDS*2);
    }
    
    static void data_handler(nrfx_i2s_buffers_t const *p_released, uint32_t status)
    {
    	if (NRFX_I2S_STATUS_NEXT_BUFFERS_NEEDED == status)
    	{
    		if(current_buffer==&initial_buffers[0])
    			current_buffer=&initial_buffers[1];
    		else if(current_buffer==&initial_buffers[1])
    			current_buffer=&initial_buffers[2];
    		else current_buffer=&initial_buffers[0];
    		nrfx_err_t err = nrfx_i2s_next_buffers_set(current_buffer);
    		if (err != NRFX_SUCCESS)
    			NRF_LOG_INFO("Error!, continuing running as if nothing happened, but you should probably investigate.\n");
    	}
    	if (p_released)
    	{
    		if (p_released->p_tx_buffer != NULL)
    		{
    			mp_block_to_fill = (uint32_t *)p_released->p_tx_buffer;
    		}
    		if (p_released->p_rx_buffer != NULL)
    		{
    			mp_block_to_check = p_released->p_rx_buffer;
    			check_rx_data(mp_block_to_check);
    		}
    	}
    }
    
    //------------------------------------------------------------------------------------
    
    int i2s_audio_init(bool k48)
    {
    	initial_buffers[0].p_tx_buffer = NULL;
    	initial_buffers[0].p_rx_buffer = NULL;
    	initial_buffers[1].p_tx_buffer = NULL;
    	initial_buffers[1].p_rx_buffer = NULL;
    	initial_buffers[2].p_tx_buffer = NULL;
    	initial_buffers[2].p_rx_buffer = NULL;
    
    	memset(&m_buffer_rx32u, 0x00, sizeof(m_buffer_rx32u));
    	initial_buffers[0].p_rx_buffer = m_buffer_rx32u[0];
    	initial_buffers[1].p_rx_buffer = m_buffer_rx32u[1];
    	initial_buffers[2].p_rx_buffer = m_buffer_rx32u[2];
    
    	nrfx_i2s_config_t config =NRFX_I2S_DEFAULT_CONFIG;
    	config.sdin_pin  = I2S_SDIN_PIN;
    	config.sdout_pin = I2S_SDOUT_PIN;
    	config.sck_pin   = I2S_SCK_PIN;
    	config.lrck_pin  = I2S_LRCK_PIN;
    	//config.mck_pin = ;
    
      config.format    = NRF_I2S_FORMAT_I2S;
      config.alignment = NRF_I2S_ALIGN_LEFT;
    	config.mode = NRF_I2S_MODE_MASTER;
    
    		config.ratio     = NRF_I2S_RATIO_32X;
    		config.mck_setup = NRF_I2S_MCK_32MDIV21;
    		config.channels = NRF_I2S_CHANNELS_STEREO;
    		config.sample_width = NRF_I2S_SWIDTH_16BIT; 
    
    
    	nrfx_err_t err_code = nrfx_i2s_init(&config, data_handler);
    	if (err_code != NRFX_SUCCESS)
    	{
    		NRF_LOG_INFO("I2S init error\n");
    		return err_code;
    	}
    	current_buffer=&initial_buffers[0];
    	err_code = nrfx_i2s_start(&initial_buffers[0], I2S_DATA_BLOCK_WORDS, 0); //start recording
    	if (err_code != NRFX_SUCCESS)
    	{
    		NRF_LOG_INFO("I2S start error\n");
    		return err_code;
    	}
    
    	return err_code;
    }
    
    int i2s_audio_stop()
    {
    	nrfx_i2s_stop();
    	nrfx_i2s_uninit();
    }
    
    //------------------------------------------------------------------------------------
    

        

    Best regards

  • Hi,

    yoyou said:
    i'v try,but it never to be called. 

    Are hp_sof_ev_handler being called?

    Try moving the code to 
    hp_sof_ev_handler()
  • Hi,  thanks for reply

    three days ago, i'v try call it in hp_sof_ev_handler(),  it lose more data.

    if possible, please check it on nrf52840-DK.

       

    Best regards

  • Hi,

    Could you check the return code of app_usbd_audio_class_tx_start()?

Related