diyAudio

diyAudio (http://www.diyaudio.com/forums/)
-   Digital Line Level (http://www.diyaudio.com/forums/digital-line-level/)
-   -   PGA2320 controlled by PIC16F887 (http://www.diyaudio.com/forums/digital-line-level/230030-pga2320-controlled-pic16f887.html)

davi_C 14th February 2013 03:50 PM

PGA2320 controlled by PIC16F887
 
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
}


kevinkr 14th February 2013 04:04 PM

:cop: Moved to Digital Line Level as Chip Amps definitely was not the right place.

macboy 14th February 2013 05:09 PM

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.

davi_C 14th February 2013 05:13 PM

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.

davi_C 14th February 2013 05:21 PM

Quote:

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!

counter culture 14th February 2013 05:50 PM

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;
    }
}


davi_C 14th February 2013 06:35 PM

Thanks for your code counter culture. The problem is that my PGA is wired to RC0 = CS, RC1 = MUTE, RD0 = Data, RD1 = CLK and actually PORTD is use as a databus.

chaparK 14th February 2013 06:56 PM

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.

counter culture 14th February 2013 09:12 PM

OK, let me have a look, I will see if I can debug your code.

@chaparK

Yes, it's true that the PIC has an SPI port, but often these are harder to debug than explicitly written code.

counter culture 14th February 2013 09:38 PM

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
}



All times are GMT. The time now is 10:36 PM.


vBulletin Optimisation provided by vB Optimise (Pro) - vBulletin Mods & Addons Copyright © 2014 DragonByte Technologies Ltd.
Copyright 1999-2014 diyAudio


Content Relevant URLs by vBSEO 3.3.2