PGA2311 code - diyAudio
Go Back   Home > Forums > Source & Line > Analog Line Level

Analog Line Level Preamplifiers , Passive Pre-amps, Crossovers, etc.

Please consider donating to help us continue to serve you.

Ads on/off / Custom Title / More PMs / More album space / Advanced printing & mass image saving
Reply
 
Thread Tools Search this Thread
Old 22nd January 2013, 07:13 AM   #1
child1 is offline child1  Denmark
diyAudio Member
 
Join Date: Jan 2013
Default PGA2311 code

Hi everyone!

I'm having trouble getting my PGA2311 to work. I have an ATTINY2313 controlling it, but i can't control the volume. Would anyone be so kind as to go through my code (attached) and look for an explanation as to why it wont work.

Thank you!

Best regards

Mads, Denmark
Attached Files
File Type: txt soundbar.txt (1.4 KB, 67 views)
File Type: txt volume c.txt (1.8 KB, 72 views)
File Type: txt volume.txt (317 Bytes, 44 views)
  Reply With Quote
Old 22nd January 2013, 08:48 AM   #2
diyAudio Member
 
jan.didden's Avatar
 
Join Date: May 2002
Location: Great City of Turnhout, Belgium
Blog Entries: 7
Can't see anything wrong.
I wonder though why the long delays in the clocking sequence?
I've done this with a PIC with a 1uS instruction cycle with no delays, reliably.
One thing you can verify is whether the Mute pin is actually set correctly.
Only advise I have is to spend some money for a low cost USB logic analyzer like the Saelig but there are more even lower in cost that do 8 bits. Pays for it very quickly!

jan
__________________
If you don't change your beliefs, your life will be like this forever. Is that good news? - W. S. Maugham
Check out Linear Audio!
  Reply With Quote
Old 22nd January 2013, 08:56 AM   #3
child1 is offline child1  Denmark
diyAudio Member
 
Join Date: Jan 2013
Thanks for the reply. The reason for the long delays is that I tried with faster delays and that didn't work, so I thought I'd give it a go with longer delays, but no difference. So to answer your question - there is no reason for the long delays...

The mute pin is high on startup and throughout the tests I've made, so that should be right!

It's really starting to annoy me, why it won't work... But hopefully someday I will find the error....
  Reply With Quote
Old 22nd January 2013, 09:18 AM   #4
diyAudio Member
 
theAnonymous1's Avatar
 
Join Date: Feb 2004
Location: Anonymityville
Maybe looking at the code for this project can help...

MiniVol PGA2320 Volume Control - error404's Audio DIY Endeavours
  Reply With Quote
Old 24th January 2013, 07:32 PM   #5
rsavas is offline rsavas  Canada
diyAudio Member
 
Join Date: Aug 2012
Location: Ontario
I have BASCOM-AVR code that I can share with you. It is written for an xmega and has a 4x40 LCD display. The basic building blocks for pre-amp/tuner

Config Portc.4 = Output
Pga_cs Alias Portc.4
Set Pga_cs 'Slave Select Pin, Connect to PGA2311-2 (CS), active low
'Dim Select_bit As Bit
'Portc_pin0ctrl = &B10_011_010 ' slew, no invert, Totempole, Pull-up (on input),Sense falling edge
'Portc_pin1ctrl = &B10_011_010 ' slew, no invert, Totempole, Pull-up (on input),Sense falling edge
'Portc_pin2ctrl = &B10_011_010 ' slew, no invert, Totempole, Pull-up (on input),Sense falling edge
'Portc_pin3ctrl = &B10_011_010 ' slew, no invert, Totempole, Pull-up (on input),Sense falling edge
Portc_pin4ctrl = &B10_011_010 ' slew, no invert, Totempole, Pull-up (on input),Sense falling edge
Portc_pin5ctrl = &B10_011_010 ' slew, no invert, Totempole, Pull-up (on input),Sense falling edge
Portc_pin7ctrl = &B10_011_010 ' slew, no invert, Totempole, Pull-up (on input),Sense falling edge
Config Spic = Hard , Master = Yes , Mode = 0 , Clockdiv = Clk32 , Data_order = Msb , Ss = None
Open "SPIC" For Binary As #3

If Encoder2old <> Encoder2 Then 'Use for Volume/Balance Function
If Pga2311_mute = 1 Then '
Volume_count = Encoder2
Encoder2old = 0
Encoder2 = 0
Volume = Volume + Volume_count
'Volume_L = Volume_L + Volume_count
'Volume_R = Volume_R + Volume_count
Disable Interrupts
Encoder2old = Encoder2
Enable Interrupts
'If Volume_L > 212 Then Volume = 212
'If Volume_R > 212 Then Volume = 212
If Volume > Volume_max Then Volume = Volume_max 'Volume Limit, max 255
If Volume < 0 Then Volume = 0
'If Volume_L < 0 Then Volume_L = 0
'If Volume_R < 0 Then Volume_R = 0
Volume_s = Volume
Volume_s = 255 - Volume_s
Volume_s = Volume_s / 2
Volume_s = 31.5 - Volume_s '31.5 -(0.5 *(255 - N))
___lcde = 1
Locate 1 , 1
'Lcd "****************************************"
Lcd "Volume L = "
Locate 1 , 12
Lcd Fusing(volume_s , "#.#") ; " dB "
Locate 1 , 21
Lcd "R = "
Lcd Fusing(volume_s , "#.#") ; " dB"
'Dim Volume_word As Word
'Dim V_right As Byte At Volume_word Overlay
'Dim V_left As Byte At Volume_word + 1 Overlay
V_right = Volume 'Assemble word for PGA2311
V_left = Volume 'Need to add balance function
Reset Pga_cs 'Select SPI Slave
Print #3 , Volume_word 'Send 16 bits to PGA2310
Set Pga_cs 'Deselect SPI Slave
End If
End If

send me a PM if you want my test code!!
  Reply With Quote
Old 25th January 2013, 11:37 AM   #6
Bonsai is offline Bonsai  Taiwan
diyAudio Member
 
Bonsai's Avatar
 
Join Date: Jul 2003
Location: Taipei, Taiwan
Let me dig mine out this weekend and you can take a look at that also.
__________________
bonsai
Amplifier Design and Construction for MUSIC! http://hifisonix.com/
  Reply With Quote
Old 25th January 2013, 12:35 PM   #7
diyAudio Member
 
Join Date: Sep 2010
Hi,

couple questions -
- are the interrupt routines that move volume up or down really called via INT0/INT1?
- if they aren't, during init you set /MUTE to 0, that means you mute the device - so I assume you measured that the pin is set to 1 during normal operation (just to reconfirm, as I don't see how the interrupts are called)
- you start with -86dB and only allow -33.5db max - is that intended? Do you check volume via the out put signal on an oscilloscope, or do you only listen? Is your source line level high enough to be audible at -33.5db?

Not sure if it matters, but on my implementation I left the clock on logical "1" when the SPI was not transmitting. (I did use the build-in serial transmitter on the 2313 in Assembler, so not possible to directly compare the code...)
  Reply With Quote
Old 25th January 2013, 06:17 PM   #8
child1 is offline child1  Denmark
diyAudio Member
 
Join Date: Jan 2013
Hi everyone ! Thanks for all your replies!

@rsavas - unfortunately, I have no experience at all with bascom but will take a look non the less...

@bonsai - Sounds great!

@rollingtube - the subroutines are called from int0/int1 on any logical change using an rentron TINY IR-II IR decoder (or at least that was what is supposed to happen )
The Mute set to 0 during init is a mistake, which have been changed
Also the max -33.5dB has been changed to unity gain (0dB) but with no difference.
I haven't checked the output signal on a oscilloscope yet, but will do this monday!
So sorry guys, despite all your help, the solution is not yet found.. :S But I will keep
on going 'till i find it!

Thanks for all your help! just keep it comming

- Mads
  Reply With Quote
Old 26th January 2013, 02:27 PM   #9
rsavas is offline rsavas  Canada
diyAudio Member
 
Join Date: Aug 2012
Location: Ontario
BASCOM-AVR= dead simple, this is why I selected this compiler over gcc!! Free demo available, all you need is a AVRISP mkII and some HW.
My first HW was a xmega BOB and the following mounted on a proto-board: from this basic setup I got my feet wet and then designed my product there-after. My test code is now at line 2357, so I can give this to you for free!! It is a lot of code, so I do not want to post it all here, but the small bit of code i have posted here, will give you an idea of how easy it really is.
The product is much more code, but I will not be releasing that, as it is of no use, as it is, unless you have the HW. If you are interested in my HW we can talk off line.

' Hardware: Sparkfun xmega100 BOB
' Newhaven NHD-0440AZ-FL-YBW
' PGA2310
' PCA9555
' 3x Bourns PC12 rotary encocders with switches
' 6x spst switches with LED (C&K K5V-BU)
' DSS BMP180
' Honeywell HumidIcon Digital Humidity/Temperature Sensor: HIH-6130/6131 Series
Dim Volume_word As Word 'Word to be written to PGA2310/2320/2311

Dim V_right As Byte At Volume_word Overlay
Dim V_left As Byte At Volume_word + 1 Overlay
Config Portk = Input
Config Portk.6 = Output 'PGA2311 Mute, active Low
Set Portk.6
Pga2311_mute Alias Portk.6

Config Portk.7 = Output 'PGA2311 ZEN, active High
Pga2311_zen Alias Portk.7
Reset Portk.7

Config Portc.4 = Output
Pga_cs Alias Portc.4

'This is all it takes to write to the PGA part
Reset Pga_cs 'Select SPI Slave
Print #3 , Volume_word 'Send 16 bits to PGA2310/11/20
Set Pga_cs 'Deselect SPI Slave

Last edited by rsavas; 26th January 2013 at 02:39 PM.
  Reply With Quote
Old 26th January 2013, 07:35 PM   #10
diyAudio Member
 
Join Date: Jun 2011
I'm not an AVR programmer, so it's difficult for me to be sure what's going on here, but I have done this with a PIC, both in assembler and in C.

First of all, I don't understand why you are doing this using interrupts.

Interrupts are always much more difficult to debug than polling loops, and you don't need interrupts to make this work. I'd rewrite the whole thing without the interrupts. I used the timer interrupts to drive a multiplexed 7-segment LED array, that's a different matter, I needed them then.

What does this:-

Code:
    PCMSK |= (1<<PCINT0); // Enable PCINT0 on PB0
...do?

PCMSK gets PCMSK bitwise OR'ed with what? What does (1<<PCINT0) mean? PCINT0 is left shifted once? One is left shifted PCINT0 times? The shift operators syntax is normally (x<<2) (x left shifted twice). Maybe AVR c is different... What is PCINT0? Why do you want to left shift it? I can see what INT0 is, I can see what PCINT is, you've got 3 ISRs INT0, INT1, and PCINT.

????????

You need to avoid comparatively obscure forms of coding like this. I've been coding in C for at least 20 years, it took me half-an-hour to figure out what it means... It's probably not your fault, you probably copied it from some smartass AVR example code.

It sets the bit called PCINT0, the one for PORTB, bit 0, in the interrupt SFR. PCINT0 is an alias for the bit number. Yes? The associated interrupt is INT0, so the ISR is passed INT0_vect?

What was wrong with

Code:
    sbi (PCMSK, PCINT0);
...??? I'd have got that immediately.

Write straightforward code where it is easy to see explicitly what is taking place. Don't combine multiple operations in a single instruction.

You have this:-

Code:
	//Enable mute
	PORTB &= 0b11111101;
and this:-

Code:
	// Disable mute
	PORTB |= (1<<PB1);
... if you want to disable the mute pin (force it to 1), write this:-

Code:
	PORTB |= 0b00000010;
or this:-

Code:
       sbi (PORTB, 1);
I can't see any point where you enable INT1 or PCINT. Presumably they are on other pins of PORTB?

What is PCINT? Why isn't it called INT3 and assigned a bit on PORTB? Is is a special feature of AVRs I can't figure out without reading the manual?

You don't need 3 files. You can keep all this stuff in 1 file. Having it in 3 files just makes it hard to read.

Code:
#include "Volume.h"
#include "avr/io.h"
#include "compat/deprecated.h"
#define F_CPU 1000000UL
#include "avr/delay.h"

int main(void);
int PGA_volume(unsigned char volume_r, unsigned char volume_l);
ISR(INT0_vect);
ISR(INT1_vect);
ISR(PCINT_vect);

unsigned char left, right;

int main(void)
{	
    DDRB = 0xFF;                         	        // Port B as output
    GIMSK |= 0b11100000;                   	        // Initialize interrupts
    MCUCR |= 0b00000101;                                // interrupt on any logical change
    PCMSK |= (1<<PCINT0);                               // Enable PCINT0 on PB0	
    PORTB |= (1<<PB7);                                  // enable ZCEN
    PORTB &= 0b11111101;                                // disable mute	
    left = 20;
    right = 20;
	
    PGA_volume(right, left);	
    while(1)
    {
        sei();                                          // Enable global interrupts
    }		
}

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

	cbi (PORTB, 6);                                 // Enable chip select
	for(i = 0 ; i < 8 ; i++)                        // Send volume right
	{
		send_r = volume_r & 0x80; 
		if (send_r == 0x80) 
		{
			sbi (PORTB, 5);                 // Set bit data
			_delay_us(100);
			sbi (PORTB, 2);                 // Set bit clock
			_delay_us(50);
			cbi (PORTB, 2);                 // Clear bit clock
			_delay_us(50);
		}

		if (send_r == 0x00)
		{
			cbi (PORTB, 5);
			_delay_us(100);
			sbi (PORTB, 2);
			_delay_us(50);
			cbi (PORTB, 2);
			_delay_us(50);
		}
		volume_r = volume_r << 1;
	}
	for(i = 0 ; i < 8 ; i++)                        // Send volume left
	{
		send_l = volume_l & 0x80;

		if (send_l == 0x80)
		{
			sbi (PORTB, 5);
			_delay_us(100);
			sbi (PORTB, 2);
			_delay_us(50);
			cbi (PORTB, 2);
			_delay_us(50);
		}

		if (send_l == 0x00)
		{
			cbi (PORTB, 5);
			_delay_us(100);
			sbi (PORTB, 2);
			_delay_us(50);
			cbi (PORTB, 2);
			_delay_us(50);
		}
		volume_l = volume_l << 1;
	}
	sbi (PORTB, 6);                                 // Disable chip select
	cbi (PORTB, 5);                                 // Clear bit data
	cbi (PORTB, 2);                                 // Clear bit clock
	return;
}

ISR(INT0_vect)                                          // Increment volume
{		
	// Disable mute
	PORTB |= (1<<PB1);
	if(left > 125 | right > 125)
	{
		left = 125;
		right = 125;
	}
	else
	{
		left = left + 1;
		right = right + 1;
	}
	PGA_volume(right,left);
}


ISR(INT1_vect)                                          // Decrement volume
{
	// Disable mute
	PORTB |= (1<<PB1);
	if(left > 125 | right > 125)
	{
		left = 125;
		right = 125;
	}
	else
	{
	left = left - 1;
	right = right - 1;
	}	
	PGA_volume(right,left);
}


ISR(PCINT_vect)                                         // Mute volume
{
	//Enable mute
	PORTB &= 0b11111101;
}
Now I can search the whole of the code in one operation for PCINT...

As far as I can tell, you've only enabled interrupts on one of the pins, that can't be helping. If the mute is on PORTB,1 which pin is calling the interrupt for INT1?

Last edited by counter culture; 26th January 2013 at 07:38 PM.
  Reply With Quote

Reply


Hide this!Advertise here!
Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are Off
Pingbacks are Off
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
PGA2311 Evaluation KatieandDad Analog Line Level 7 3rd February 2013 04:58 PM
PGA2311 daisy-chaining yallo Chip Amps 2 23rd March 2012 04:39 PM
Problem witht [code]blah[/code] ? elseif Forum Problems 1 17th August 2008 12:30 AM
How to use PGA2311 in a gainclone? Spasticteapot Chip Amps 12 10th March 2007 09:42 PM
PGA2311 control Hisatugo Digital Source 0 15th June 2005 10:07 PM


New To Site? Need Help?

All times are GMT. The time now is 09:41 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