Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
14 years ago

Printing 32bit signed 2s complement data via JTAG UART

I'm trying to print out samples generated by the WM8731 audio codec on the DE2 board via the JTAG UART in a Nios II system. The samples are deserialized in Verilog HDL, squared (this is needed for a different module but it is the part that's not working) then transferred to the Nios system to be printed on the PC terminal. The C program to print out the data is:


# define USB_Ctrl (volatile char *) 0x00005000
# define Data_in_1 (volatile char *) 0x00005010
# define Data_in_2 (volatile char *) 0x00005020
# define Data_in_3 (volatile char *) 0x00005030
# define Data_in_4 (volatile char *) 0x00005040
int main()
{ 
  alt_32 data_1;
  alt_32 data_2;
  alt_32 data_3;
  alt_32 data_4;
  int sw = 0;
  while(1)
  {
    // Get data from FPGA system
    sw = *USB_Ctrl;
    data_1 = *Data_in_1;
    data_2 = *Data_in_2;
    data_3 = *Data_in_3;
    data_4 = *Data_in_4;
    
    // Only print out data if SW is HIGH
    if(sw)
    {
      printf("audR: %d \t audL: %d\t audL2: %d\t\t filt: %d\n", data_1, data_2, data_3, data_4);
      //printf("%d\n", data_1);
    }
  }
  return 0;
}

The only way I've been able to get it to properly print out negative numbers is to use volatile char * but char is only 8 bits and I need 32 bits. And then when audL is squared to get audL2, the results are always wrong for anything above 11 for some reason (ie it will properly square anything from +/- 0 to 11 but nothing else). Changing this to alt_32 doesn't print out the negative values (ie it will print 65534 instead of -2). What am I doing wrong?

5 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    db800: probably your hardware is returning signed 16bit values. So you'll need to use (something equivalent to) 'volatile short' at some point.

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Yes, the audio codec returns a 16bit signed 2s complement sample which I am sending to the Nios system to be printed over JTAG UART (after squaring it).

    Input signal: 2.4 Vpp, 500Hz, sine wave

    Using volatile char *:

    
    audR: 1 	 audL: -126	 audL2: 4
    audR: 2 	 audL: 94	 audL2: -124
    audR: 1 	 audL: 110	 audL2: 68	
    audR: 1 	 audL: 11	 audL2: 121
    audR: -3 	 audL: 8	 audL2: 64
    audR: 2 	 audL: 7	 audL2: 49
    audR: -1 	 audL: -3	 audL2: 9
    audR: 0 	 audL: 12	 audL2: -112
    

    Using volatile short * (obviously wrong results for audL2 since it is 32 bits but even audL is very different from char results):

    
    audR: 0 	 audL: 12949	 audL2: -30023
    audR: 1 	 audL: 956	 audL2: -3568
    audR: 1 	 audL: -12180	 audL2: -21104
    audR: -3 	 audL: 5486	 audL2: 15172
    audR: 0 	 audL: 11626	 audL2: 28644
    audR: 2 	 audL: -6731	 audL2: 20985
    

    Using

    #define USB_Ctrl (volatile char *) 0x00005000 
    # define Data_in_1 (volatile alt_16 *) 0x00005010 // right channel samples
    # define Data_in_2 (volatile alt_16 *) 0x00005020 // left channel samples
    # define Data_in_3 (volatile alt_32 *) 0x00005030 // left channel samples squared
    # define Data_in_4 (volatile alt_32 *) 0x00005040 // filter results
    audR: -2 	 audL: 165	 audL2: 27225		 filt: 26076439
    audR: -1 	 audL: 10419	 audL2: 108555561	 filt: 146741412
    audR: -2 	 audL: -1139	 audL2: 1297321		 filt: 16184391
    audR: -2 	 audL: 1243	 audL2: 1545049		 filt: 36079690
    

    Removes the negative results problem, but I don't know how to make sense of this sample data now. how do i properly convert these sample values to a real voltage? Since I'm using 16bits, the ADC has a resolution of -32768 to +32767. The step size would be Q = (3.6 - 1.8 V)/2^16 = 0.0000275 V = 0.0275 mV (I'm a little unsure of the input voltage range for WM8731, the datasheet says the analog supply range is 1.8-3.6V). Is this correct?
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I've been sending in a square wave and sine wave of varying amplitude (0 V up to 6.2 V). Clipping doesn't occur until 6.2 V so this must be the max input range (I appear to have been making a stupid mistake and taking the chip supply voltage as the input signal voltage). Multiplying the samples by Q = (6.2 - 0V)/2^16 = 0.0946 now gives me the proper results (I hope!).

    2 Vpp, 1Khz, square wave input signal gives me ADC samples of approximately +/- 1000, which I assume is +/- 1V. Varying the input amplitude to 3 Vpp gives ADC samples of +/- 1500 which also appears correct.

    However, a secondary problem has shown up: DC input signals don't work. The ADC samples remain approximately 0 even with a varying DC input. I configured the WM8731 codec to disable the ADC high pass filter but it still appears to be removing the DC signal...

    --- Quote Start ---

    From the datasheet:

    When the high-pass filter is enabled the dc offset is continuously calculated and subtracted from the input signal. By setting HPOR the last calculated dc offset value is stored when the high-pass filter is disable and will continue to be subtracted from the input signal

    --- Quote End ---

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    You can use the Vpp data from your square waves for the calculation.