PGA2320 controlled by PIC16F887

davi_C

Member
2009-11-16 2:03 am
Hello all,

I really need your help here. I've been searching for a while to find the solution and now...still not working. Here is my problem: I'm using a PIC16F887 as MCU and the PGA2320 as volume controller. I hooked it up and verified all my wiring (make sure everything was fine), including debuging step by step and all the pins are well configured and running as intend. The problem is the PGA always remain in high impedance whatever the data I sent from 0x00 to
0xFF. I've also tried differents approach for the clock, chip select but still not working. Here is a piece of code, if you can help me, I'll appreciate.

Code:
void
volume_set(unsigned char left, unsigned char right)
{
	unsigned char i, b;
	VOL_CS = 0;	// Enable the volume control
	b=left;
	for (i=8;i>0;i--) {	// Clock out right data
		unsigned char x= 1 << (i-1);
		if (b>=x) {
			VOL_D=1;
			b-=x;
		}
		else {
			VOL_D=0;
		}
		VOL_CLK = 0;
		VOL_CLK = 1;
	}
	b=right;
	for (i=8;i>0;i--) {	// Clock out right data
		unsigned char x= 1 << (i-1);
		if (b>=x) {
			VOL_D=1;
			b-=x;
		}
		else {
			VOL_D=0;
		}
		VOL_CLK = 0;
		VOL_CLK = 1;
	}
	VOL_CS = 1;		// Disable the volume control
}
 

davi_C

Member
2009-11-16 2:03 am
Did you pull /MUTE (pin 8) high to disable mute?
Try adding some NOP instructions after setting each output signal to slow things down, especially between seeting clk low then high again.

Hi macboy,
The MUTE is high when everything startup. I've tried to add 10 uS for the delay between each transition of Clock. Still not working. Thanks for your help!
 
Long winded, uses a lot of memory, but it works.

l_buf and r_buf are global variables, unsigned char

Code:
/*RE2 = SCK*/
/*RE1 = CS*/
/*RE0 = SDI*/

void xmit(void){
    x0buf=l_buf & 0b10000000;
    x1buf=l_buf & 0b01000000;  
    x2buf=l_buf & 0b00100000;  
    x3buf=l_buf & 0b00010000;
    x4buf=l_buf & 0b00001000;
    x5buf=l_buf & 0b00000100;
    x6buf=l_buf & 0b00000010;
    x7buf=l_buf & 0b00000001;

    x8buf=r_buf & 0b10000000;
    x9buf=r_buf & 0b01000000;
    xabuf=r_buf & 0b00100000;
    xbbuf=r_buf & 0b00010000;
    xcbuf=r_buf & 0b00001000;
    xdbuf=r_buf & 0b00000100;
    xebuf=r_buf & 0b00000010;
    xfbuf=r_buf & 0b00000001;
    PORTE=0b11111111;
    PORTE=0b11111101;
    if(x0buf){
        PORTE=0b11111001;
        PORTE=0b11111101;
    }
    else{
        PORTE=0b11111000;
        PORTE=0b11111100;
    }
    if(x1buf){
        PORTE=0b11111001;
        PORTE=0b11111101;
    }
    else{
        PORTE=0b11111000;
        PORTE=0b11111100;
    }
    if(x2buf){
        PORTE=0b11111001;
        PORTE=0b11111101;
    }
    else{
        PORTE=0b11111000;
        PORTE=0b11111100;
    }
    if(x3buf){
        PORTE=0b11111001;
        PORTE=0b11111101;
    }
    else{
        PORTE=0b11111000;
        PORTE=0b11111100;
    }
    if(x4buf){
        PORTE=0b11111001;
        PORTE=0b11111101;
    }
    else{
        PORTE=0b11111000;
        PORTE=0b11111100;
    }
    if(x5buf){
        PORTE=0b11111001;
        PORTE=0b11111101;
    }
    else{
        PORTE=0b11111000;
        PORTE=0b11111100;
    }
    if(x6buf){
        PORTE=0b11111001;
        PORTE=0b11111101;
    }
    else{
        PORTE=0b11111000;
        PORTE=0b11111100;
    }
    if(x7buf){
        PORTE=0b11111001;
        PORTE=0b11111101;
    }
    else{
        PORTE=0b11111000;
        PORTE=0b11111100;
    }
    if(x8buf){
        PORTE=0b11111001;
        PORTE=0b11111101;
    }
    else{
        PORTE=0b11111000;
        PORTE=0b11111100;
    }
    if(x9buf){
        PORTE=0b11111001;
        PORTE=0b11111101;
    }
    else{
        PORTE=0b11111000;
        PORTE=0b11111100;
    }
    if(xabuf){
        PORTE=0b11111001;
        PORTE=0b11111101;
    }
    else{
        PORTE=0b11111000;
        PORTE=0b11111100;
    }
    if(xbbuf){
        PORTE=0b11111001;
        PORTE=0b11111101;
    }
    else{
        PORTE=0b11111000;
        PORTE=0b11111100;
    }
    if(xcbuf){
        PORTE=0b11111001;
        PORTE=0b11111101;
    }
    else{
        PORTE=0b11111000;
        PORTE=0b11111100;
    }
    if(xdbuf){
        PORTE=0b11111001;
        PORTE=0b11111101;
    }
    else{
        PORTE=0b11111000;
        PORTE=0b11111100;
    }
    if(xebuf){
        PORTE=0b11111001;
        PORTE=0b11111101;
    }
    else{
        PORTE=0b11111000;
        PORTE=0b11111100;
    }
    if(xfbuf){
        PORTE=0b11111001;
        PORTE=0b11111101;
        PORTE=0b11111111;
        PORTE=0b11111111;
    }
    else{
        PORTE=0b11111000;
        PORTE=0b11111100;
        PORTE=0b11111110;
        PORTE=0b11111111;
    }
}
 
I had a quick look at your code. It seems to me very complicated.

The PGA control port is SPI-like, with a Chip Select, a serial clock, data in and optionally data out.

Your micro PIC16F887 has a SPI port.

So why the hell are you bit-banging the data? :)

If your board is already hard-wired, well then it's too late. Ignore my post.

Otherwise just plug the micro's SPI to the PGA control port, use one GPIO on the micro that will act as the CS. Configure your SPI port, send your data by writing into the shift register and it's done. This is the proper way of doing it I believe.
 
You could try this... untested.

Otherwise you could try PMing child1, this bit of code is modified from some I sent him, I know he got his working, I don't know whether he used this...

Code:
/*PORTC, 0 = CS*/
/*PORTD, 0 = Data*/
/*PORTD, 1 = Clk*/

void PGA_volume(unsigned char volume_r, unsigned char volume_l)
{
	unsigned char i;
	unsigned char send_r, send_l;

	sbi (PORTD,0);                                  // Set bit data
	sbi (PORTD,1);                                  // Set bit clock
	cbi (PORTC, 0);                                 // Enable chip select

	for(i = 0 ; i < 8 ; i++)                         // Send volume right
	{
		send_r = volume_r & 0b10000000; 
		if (send_r){
			sbi (PORTD,0);                 // Set bit data
			cbi (PORTD,1);                 // Set bit clock
			sbi (PORTD,1);                 // Clear bit clock
		}
                else{
			cbi (PORTD,0);                 // Clear bit data
			cbi (PORTD,1);                 // Set bit clock
			sbi (PORTD,1);                 // Clear bit clock
		}
		volume_r = volume_r << 1;
	}
	for(i = 0 ; i < 8 ; i++)                        // Send volume left
	{
		send_l = volume_l & 0b10000000;
		if (send_l){
			sbi (PORTD,0);
			cbi (PORTD,1);
			sbi (PORTD,1);
		}
                else{
			cbi (PORTD,0);
			cbi (PORTD,1);
			sbi (PORTD,1);
		}
		volume_l = volume_l << 1;
	}
	sbi (PORTC,0);                                 // Disable chip select
	sbi (PORTD,0);                                 // Set bit data
	sbi (PORTD,1);                                 // Set bit clock
}