Jump to content

PGA2311 STM32F4 HowTo?


mwpost
 Share

Recommended Posts

Hi,

 

Ok good news, I got it working :smile:

I use PGA4311 (SMD IC), and my mute pin, after living 10 years in a junk box was broken (I made an error and connect it to GND instead on +5V on my original PCB, and then use a wire to correct this... but the pin didn't handle it over the years).

 

So the modification I made is in APP_init:

  MIOS32_SPI_IO_Init(2, MIOS32_SPI_PIN_DRIVER_WEAK);
  MIOS32_SPI_TransferModeInit(2, MIOS32_SPI_MODE_CLK0_PHASE0, MIOS32_SPI_PRESCALER_16); // ca. 5 MBit

 

I don't really understand how this and prescaler work, but with those settings I can set the gain.

I'll add encoder support for volume change and post the source code.

Edited by pilo
Link to comment
Share on other sites

Here's my test app, it should work now (unless you have an hardware issue).

 

/*
 * MIOS32 TI PGA2310/2311/4311 test app 
 *
 * ==========================================================================
 *
 *  Copyright © 2015 pilo ()
 *  Licensed for personal non-commercial use only.
 *  All other rights reserved.
 * 
 * ==========================================================================
 */

/////////////////////////////////////////////////////////////////////////////
// Include files
/////////////////////////////////////////////////////////////////////////////

#include <mios32.h>
#include "app.h"

// warning, buffer should be at least 9 byte long!
void PGAGainTodB(char *buffer, u8 gain) {
  if(gain == 0) {
    sprintf(buffer, "mute");
    return;
  }
  
  // else
  int _dB = 315 - (1275 - gain * 5);
  int dB = fabs(_dB / 10);
  int mod = fabs(_dB % 10);
  
  if(mod == 0) 
    sprintf(buffer, "%ddB", _dB / 10);
  else
    sprintf(buffer, "%s%d%s%ddB", 
	    _dB < 0 ? "-" : "", // sign
	    dB,  
	    mod != 0 ? "." : "", 
	    mod != 0 ? mod : "");
}

void SetPGAGain(u8 leftGain, u8 rightGain) {
  MIOS32_SPI_RC_PinSet (2,0,0);
  MIOS32_SPI_TransferByte(2, rightGain); // right
  MIOS32_SPI_TransferByte(2, leftGain); // left
  MIOS32_SPI_TransferByte(2, rightGain); // 3 (for PGA4311)
  MIOS32_SPI_TransferByte(2, leftGain); // 4
  MIOS32_SPI_RC_PinSet (2,0,1);

  //MIOS32_MIDI_SendDebugMessage("SetPGAGain : %d %d\n", leftGain, rightGain);
}

u8 volumeEncPos = 192; // 0dB
#define NUM_ENCODERS 64

/////////////////////////////////////////////////////////////////////////////
// This hook is called after startup to initialize the application
/////////////////////////////////////////////////////////////////////////////
void APP_Init(void)
{
  // initialize all LEDs
  MIOS32_BOARD_LED_Init(0xffffffff);

  // initialize SPI IO pins and protocol
  MIOS32_SPI_IO_Init(2, MIOS32_SPI_PIN_DRIVER_WEAK);
  MIOS32_SPI_TransferModeInit(2, MIOS32_SPI_MODE_CLK0_PHASE0, MIOS32_SPI_PRESCALER_16); // ca. 5 MBit

  // initialize rotary encoders of the same type (DETENTED2)
  int enc;
  for(enc=0; enc<NUM_ENCODERS; ++enc) {
    u8 pin_sr = (enc >> 2) + 1; // each DIN SR has 4 encoders connected
    u8 pin_pos = (enc & 0x3) << 1; // Pin position of first ENC channel: either 0, 2, 4 or 6

    mios32_enc_config_t enc_config = MIOS32_ENC_ConfigGet(enc);
    enc_config.cfg.type = DETENTED2; // see mios32_enc.h for available types
    enc_config.cfg.sr = pin_sr;
    enc_config.cfg.pos = pin_pos;
#if 1
    // normal speed, incrementer either 1 or -1
    enc_config.cfg.speed = NORMAL;
    enc_config.cfg.speed_par = 0;
#else
    // higher incrementer values on fast movements
    enc_config.cfg.speed = FAST;
    enc_config.cfg.speed_par = 2;
#endif
    MIOS32_ENC_ConfigSet(enc, enc_config);
  }
}


/////////////////////////////////////////////////////////////////////////////
// This task is running endless in background
/////////////////////////////////////////////////////////////////////////////
void APP_Background(void)
{
  MIOS32_MIDI_SendDebugMessage("Started PGA test app\n");

  SetPGAGain(volumeEncPos, volumeEncPos);

  while(1) {
  }
}


/////////////////////////////////////////////////////////////////////////////
// This hook is called each mS from the main task which also handles DIN, ENC
// and AIN events. You could add more jobs here, but they shouldn't consume
// more than 300 uS to ensure the responsiveness of buttons, encoders, pots.
// Alternatively you could create a dedicated task for application specific
// jobs as explained in $MIOS32_PATH/apps/tutorials/006_rtos_tasks
/////////////////////////////////////////////////////////////////////////////
void APP_Tick(void)
{
  // PWM modulate the status LED (this is a sign of life)
  u32 timestamp = MIOS32_TIMESTAMP_Get();
  MIOS32_BOARD_LED_Set(1, (timestamp % 20) <= ((timestamp / 100) % 10));
}


/////////////////////////////////////////////////////////////////////////////
// This hook is called each mS from the MIDI task which checks for incoming
// MIDI events. You could add more MIDI related jobs here, but they shouldn't
// consume more than 300 uS to ensure the responsiveness of incoming MIDI.
/////////////////////////////////////////////////////////////////////////////
void APP_MIDI_Tick(void)
{
}


/////////////////////////////////////////////////////////////////////////////
// This hook is called when a MIDI package has been received
/////////////////////////////////////////////////////////////////////////////
void APP_MIDI_NotifyPackage(mios32_midi_port_t port, mios32_midi_package_t midi_package)
{
}


/////////////////////////////////////////////////////////////////////////////
// This hook is called before the shift register chain is scanned
/////////////////////////////////////////////////////////////////////////////
void APP_SRIO_ServicePrepare(void)
{
}


/////////////////////////////////////////////////////////////////////////////
// This hook is called after the shift register chain has been scanned
/////////////////////////////////////////////////////////////////////////////
void APP_SRIO_ServiceFinish(void)
{
}


/////////////////////////////////////////////////////////////////////////////
// This hook is called when a button has been toggled
// pin_value is 1 when button released, and 0 when button pressed
/////////////////////////////////////////////////////////////////////////////
void APP_DIN_NotifyToggle(u32 pin, u32 pin_value)
{
}


/////////////////////////////////////////////////////////////////////////////
// This hook is called when an encoder has been moved
// incrementer is positive when encoder has been turned clockwise, else
// it is negative
/////////////////////////////////////////////////////////////////////////////
void APP_ENC_NotifyChange(u32 encoder, s32 incrementer)
{
  int value = volumeEncPos + incrementer;

  // clamp the value
  if(value < 0)
    value = 0;
  
  if(value > 255)
    value = 255;
  
  // set the gain
  volumeEncPos = value;
  SetPGAGain(volumeEncPos, volumeEncPos);
  
  // print gain in dB
  char dbBuffer[9];
  PGAGainTodB(dbBuffer, volumeEncPos);
  MIOS32_MIDI_SendDebugMessage("%s\n", dbBuffer);
}


/////////////////////////////////////////////////////////////////////////////
// This hook is called when a pot has been moved
/////////////////////////////////////////////////////////////////////////////
void APP_AIN_NotifyChange(u32 pin, u32 pin_value)
{
}

Edited by pilo
Link to comment
Share on other sites

Vive la France, Pilo!

 

Many thousand "Thanks" for this so far. :thumbsup:  It seems to - for whatever reason - both :excl: of my PGA2311s are defect.  The code doesn't work with none of them. And if this works for you, a hardware issue is my last guess. I'll order new ICs and will try your code again with these. I'll let you know as soon as I have received them. The ICs are very expensive in Germany so I'll order them in the States. But this will take approx 2 weeks best case unless customs clearance will be quick.

 

Kind regards to St. Etienne!

 

mwpost

Link to comment
Share on other sites

Thank you ;)

When i said it might be a hardware issue, I was thinking about something like wiring issue.

I fried my testing psu (for the analog +5/-5v) yesterday while working on this, I might have made a modification to the code that prevent it from working after (I wrote the value to dB code after my PSU made some smoke).

Also it would be a shame both your PGA chips are broken. I think before ordering new ones there are other things to check ;)

First, I use lpc17 core, I don't think it should make a big difference, but maybe it is.

Then how did you wire your power supply? I use the +5v from the core for the digital side of the PGA, and another external PSU for the analog side (I build a new one today, not finished yet). Both ground (analog and digital) are connected.

Mute and ZCEN are connected to the +5v from the core.

Of course analog and digital +5v ARE NOT connected together.

Double check your wiring, there might be an error somewhere. No sound at all when you run the application? (Without turning any encoder)

Edited by pilo
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

×
×
  • Create New...