AD1938: what is the formula to transform the data received from AD1938 into volts?

I want to display a sine wave signal in a software program that I apply to the analog audio input of the codec. I get the data in the receive buffer, then convert it from a fixed-point format to a 32-bit floating-point format, but I do not know how to convert this data into an effective signal (amplitude in volts). Thank you.

Parents
  • So I use this configuration for AD1938:

    /* Setup the SPI parameters here in a buffer first */
    unsigned char ConfigParam1938[] = {
    (AD1938_ADDR),    CLKCTRL0,       DIS_ADC_DAC | INPUT256 | PLL_IN_MCLK | MCLK_OUT_OFF |                                                            PLL_PWR_DWN,
    (AD1938_ADDR),    CLKCTRL1,       DAC_CLK_PLL | ADC_CLK_PLL | DIS_VREF,
    (AD1938_ADDR),    DACCTRL0,       DAC_FMT_TDM | DAC_BCLK_DLY_1 | DAC_SR_48K,

    (AD1938_ADDR),    DACCTRL1,       DAC_LRCLK_POL_INV | DAC_BCLK_POL_INV | DAC_CHANNELS_8 |                                                                              DAC_LATCH_MID | DAC_BCLK_MASTER | DAC_LRCLK_MASTER,
    (AD1938_ADDR),    DACCTRL2,      DAC_WIDTH_24 | DAC_DEEMPH_32K,
    (AD1938_ADDR),    DACVOL_L1,    DACVOL_BEARABLE, /* Slot 4, Vout 1. */
    (AD1938_ADDR),    DACVOL_R1,   DACVOL_BEARABLE, /* Slot 5, Vout 5. */
    (AD1938_ADDR),    DACVOL_L2,    DACVOL_BEARABLE, /* Slot 6, Vout 2. */
    (AD1938_ADDR),    DACVOL_R2,    DACVOL_BEARABLE, /* Slot 7, Vout 6. */
    (AD1938_ADDR),    DACVOL_L3,    DACVOL_BEARABLE, /* Slot 0, Vout 3. */
    (AD1938_ADDR),    DACVOL_R3,   DACVOL_BEARABLE, /* Slot 1, Vout 7. */
    (AD1938_ADDR),    DACVOL_L4,    DACVOL_BEARABLE, /* Slot 2, Vout 4. */
    (AD1938_ADDR),    DACVOL_R4,    DACVOL_BEARABLE, /* Slot 3, Vout 8. */
    (AD1938_ADDR),    ADCCTRL0,       ADC_SR_48K,

    (AD1938_ADDR),    ADCCTRL1,       ADC_LATCH_MID | ADC_FMT_AUX | ADC_BCLK_DLY_1 | ADC_WIDTH_24,
    (AD1938_ADDR),    ADCCTRL2,       ADC_LRCLK_FMT_PULSE | ADC_BCLK_SLAVE | ADC_LRCLK_SLAVE |                                                            ADC_BCLK_SRC_INTERNAL | ADC_LRCLK_POL_INV | ADC_BCLK_POL_INV |                                                             ADC_CHANNELS_8,

    (AD1938_ADDR),    CLKCTRL0,       DIS_ADC_DAC | PLL_IN_MCLK | MCLK_OUT_OFF | INPUT256 | PLL_PWR_UP,
    (AD1938_ADDR),    CLKCTRL0,       ENA_ADC_DAC | PLL_IN_MCLK | MCLK_OUT_OFF | INPUT256 | PLL_PWR_UP,
    };

    and in my firmware I use a falling edge interrupt on the TDM_FS (SPORT 2 for transmision SPORT 3 for reception).

    In the interrupt I change the ping-pong buffer then I undersample the signal (the sample rate of codec is 32 KHz and I want 1 KHz):

    if(g_analog_input_cntr == 32)
    {
       g_analog_input_buffer[g_analog_input_state.sample_cntr_in] = g_analog_input_state.chL_mean / (float)0x20;
       g_analog_input_buffer[g_analog_input_state.sample_cntr_in + ANALOG_INPUT_CHANNEL_BUFFER_SIZE] =

                                              g_analog_input_state.chR_mean / (float)0x20;
       g_analog_input_state.chL_mean = 0;
       g_analog_input_state.chR_mean = 0;

       g_analog_input_cntr = 0;
       g_analog_input_state.sample_cntr_in = (g_analog_input_state.sample_cntr_in + 1) & ANALOG_INPUT_BUFFER_MASK;
    }
    else
    {
       g_analog_input_state.chL_mean += (float)(*(rx_block_pointer[buffer_cntr]) << 8) / (float)(0x7FFFFFFF);
       g_analog_input_state.chR_mean += (float)(*(rx_block_pointer[buffer_cntr] + 1) << 8) / (float)(0x7FFFFFFF);

       //g_analog_input_state.chL_mean += __builtin_conv_RtoF(*(rx_block_pointer[buffer_cntr]));
       //g_analog_input_state.chR_mean += __builtin_conv_RtoF(*(rx_block_pointer[buffer_cntr] + 1));

       g_analog_input_cntr++;
    }

    I want to transform the float values resulted from the fixed-point to floating-point conversion to amplitude values from the input sine wave. 

    What should I use for fixed-point to floating-point conversion? The __builtin_conv_RtoF() function or (float)(*(rx_block_pointer[buffer_cntr]) << 8) / (float)(0x7FFFFFFF)? Also, I use only IN1L and IN1R inputs so I should read only the first 2 slots of the rx buffer?

Reply
  • So I use this configuration for AD1938:

    /* Setup the SPI parameters here in a buffer first */
    unsigned char ConfigParam1938[] = {
    (AD1938_ADDR),    CLKCTRL0,       DIS_ADC_DAC | INPUT256 | PLL_IN_MCLK | MCLK_OUT_OFF |                                                            PLL_PWR_DWN,
    (AD1938_ADDR),    CLKCTRL1,       DAC_CLK_PLL | ADC_CLK_PLL | DIS_VREF,
    (AD1938_ADDR),    DACCTRL0,       DAC_FMT_TDM | DAC_BCLK_DLY_1 | DAC_SR_48K,

    (AD1938_ADDR),    DACCTRL1,       DAC_LRCLK_POL_INV | DAC_BCLK_POL_INV | DAC_CHANNELS_8 |                                                                              DAC_LATCH_MID | DAC_BCLK_MASTER | DAC_LRCLK_MASTER,
    (AD1938_ADDR),    DACCTRL2,      DAC_WIDTH_24 | DAC_DEEMPH_32K,
    (AD1938_ADDR),    DACVOL_L1,    DACVOL_BEARABLE, /* Slot 4, Vout 1. */
    (AD1938_ADDR),    DACVOL_R1,   DACVOL_BEARABLE, /* Slot 5, Vout 5. */
    (AD1938_ADDR),    DACVOL_L2,    DACVOL_BEARABLE, /* Slot 6, Vout 2. */
    (AD1938_ADDR),    DACVOL_R2,    DACVOL_BEARABLE, /* Slot 7, Vout 6. */
    (AD1938_ADDR),    DACVOL_L3,    DACVOL_BEARABLE, /* Slot 0, Vout 3. */
    (AD1938_ADDR),    DACVOL_R3,   DACVOL_BEARABLE, /* Slot 1, Vout 7. */
    (AD1938_ADDR),    DACVOL_L4,    DACVOL_BEARABLE, /* Slot 2, Vout 4. */
    (AD1938_ADDR),    DACVOL_R4,    DACVOL_BEARABLE, /* Slot 3, Vout 8. */
    (AD1938_ADDR),    ADCCTRL0,       ADC_SR_48K,

    (AD1938_ADDR),    ADCCTRL1,       ADC_LATCH_MID | ADC_FMT_AUX | ADC_BCLK_DLY_1 | ADC_WIDTH_24,
    (AD1938_ADDR),    ADCCTRL2,       ADC_LRCLK_FMT_PULSE | ADC_BCLK_SLAVE | ADC_LRCLK_SLAVE |                                                            ADC_BCLK_SRC_INTERNAL | ADC_LRCLK_POL_INV | ADC_BCLK_POL_INV |                                                             ADC_CHANNELS_8,

    (AD1938_ADDR),    CLKCTRL0,       DIS_ADC_DAC | PLL_IN_MCLK | MCLK_OUT_OFF | INPUT256 | PLL_PWR_UP,
    (AD1938_ADDR),    CLKCTRL0,       ENA_ADC_DAC | PLL_IN_MCLK | MCLK_OUT_OFF | INPUT256 | PLL_PWR_UP,
    };

    and in my firmware I use a falling edge interrupt on the TDM_FS (SPORT 2 for transmision SPORT 3 for reception).

    In the interrupt I change the ping-pong buffer then I undersample the signal (the sample rate of codec is 32 KHz and I want 1 KHz):

    if(g_analog_input_cntr == 32)
    {
       g_analog_input_buffer[g_analog_input_state.sample_cntr_in] = g_analog_input_state.chL_mean / (float)0x20;
       g_analog_input_buffer[g_analog_input_state.sample_cntr_in + ANALOG_INPUT_CHANNEL_BUFFER_SIZE] =

                                              g_analog_input_state.chR_mean / (float)0x20;
       g_analog_input_state.chL_mean = 0;
       g_analog_input_state.chR_mean = 0;

       g_analog_input_cntr = 0;
       g_analog_input_state.sample_cntr_in = (g_analog_input_state.sample_cntr_in + 1) & ANALOG_INPUT_BUFFER_MASK;
    }
    else
    {
       g_analog_input_state.chL_mean += (float)(*(rx_block_pointer[buffer_cntr]) << 8) / (float)(0x7FFFFFFF);
       g_analog_input_state.chR_mean += (float)(*(rx_block_pointer[buffer_cntr] + 1) << 8) / (float)(0x7FFFFFFF);

       //g_analog_input_state.chL_mean += __builtin_conv_RtoF(*(rx_block_pointer[buffer_cntr]));
       //g_analog_input_state.chR_mean += __builtin_conv_RtoF(*(rx_block_pointer[buffer_cntr] + 1));

       g_analog_input_cntr++;
    }

    I want to transform the float values resulted from the fixed-point to floating-point conversion to amplitude values from the input sine wave. 

    What should I use for fixed-point to floating-point conversion? The __builtin_conv_RtoF() function or (float)(*(rx_block_pointer[buffer_cntr]) << 8) / (float)(0x7FFFFFFF)? Also, I use only IN1L and IN1R inputs so I should read only the first 2 slots of the rx buffer?

Children
No Data