|
|
View previous topic :: View next topic |
Author |
Message |
tonkostz
Joined: 07 May 2011 Posts: 54 Location: Bulgaria
|
Volume control chip M62429 driver |
Posted: Wed Jan 01, 2025 5:15 am |
|
|
I am trying to adapt an arduino driver for a olume control chip M62429 to CCS C compiler but i am not sure i understand this section of the code. Would you help on this?
Code: | // Send control word
for (uint8_t i = 0; i < 11; i++) {
delayMicroseconds (2);
digitalWrite (_pin_data, 0);
delayMicroseconds (2);
digitalWrite (_pin_clk, 0);
delayMicroseconds (2);
digitalWrite (_pin_data, (data_word >> i) & 0x01);
delayMicroseconds (2);
digitalWrite (_pin_clk, 1);
}
delayMicroseconds (2);
digitalWrite (_pin_data, 1);
delayMicroseconds (2);
digitalWrite (_pin_clk, 0);
} |
This is to complete code:
Code: | /*!
* This is a library for M62429/FM62429 Serial data control dual electronics volume chips.
*
* Written by CGrassin.
*/
#include "Arduino.h"
#include "M62429.h"
M62429::M62429 (uint8_t pin_clk, uint8_t pin_data){
_pin_data = pin_data;
_pin_clk = pin_clk;
}
/*
* Sets the volume of one on both channel of the 62429.
*
* Parameters:
* attenuation, from 0 to 83dB
* both, 0 (default)=both channels or 1=individual
* channel, 0=channel 1, 1 = channel 2, no effect if both=0
*/
void M62429::_setVolume(uint8_t attenuation, uint8_t channel, uint8_t both){
uint16_t data_word = 0x00;
// Sanity checks on parameters
if(both>1 || channel>1)
return;
if(attenuation > 83)
attenuation = 83;
// Convert volume to attenuation
//uint8_t attenuation = (volume > 100) ? 0 : (((volume * 83) / -100) + 83);
// Build control word (11 bits)
data_word |= (channel << 0); // Channel select: 0=ch1, 1=ch2
data_word |= (both << 1); // Individual/both select: 0=both, 1=individual
data_word |= ((21 - (attenuation / 4)) << 2); // ATT1: coarse attenuator, steps of -4dB
data_word |= ((3 - (attenuation % 4)) << 7); // ATT2: fine attenuator, steps of -1dB)
data_word |= (0b11 << 9); // 2 last bits must be 1
// Send control word
for (uint8_t i = 0; i < 11; i++) {
delayMicroseconds (2);
digitalWrite (_pin_data, 0);
delayMicroseconds (2);
digitalWrite (_pin_clk, 0);
delayMicroseconds (2);
digitalWrite (_pin_data, (data_word >> i) & 0x01);
delayMicroseconds (2);
digitalWrite (_pin_clk, 1);
}
delayMicroseconds (2);
digitalWrite (_pin_data, 1);
delayMicroseconds (2);
digitalWrite (_pin_clk, 0);
}
void M62429::setVolumeBoth(uint8_t attenuation){
_setVolume(attenuation, 0, 0);
}
void M62429::setVolumeCh1(uint8_t attenuation){
_setVolume(attenuation, 0, 1);
}
void M62429::setVolumeCh2(uint8_t attenuation){
_setVolume(attenuation, 1, 1);
} |
M62429.h
Code: | /*!
* This is a library for M62429/FM62429 Serial data control dual electronics volume chips.
*
* Written by CGrassin.
*/
#ifndef M62429_H
#define M62429_H
class M62429 {
public:
M62429 (uint8_t pin_clk, uint8_t pin_data);
void setVolumeBoth(uint8_t attenuation);
void setVolumeCh1 (uint8_t attenuation);
void setVolumeCh2 (uint8_t attenuation);
private:
uint8_t _pin_data, _pin_clk;
void _setVolume(uint8_t attenuation, uint8_t channel, uint8_t both);
};
#endif |
As i understood it is basically a dual digital potentiometer like MCP42xx for which i have driver. Is it possible to adapt it for this chip?
Thanks! |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19588
|
|
Posted: Wed Jan 01, 2025 8:21 am |
|
|
Read the dats sheet!.......
Seriously this is a very easy chip to drive.
All you do it clock 11 bits to the chip.
Code: |
#define CLOCK_PIN pin_xx //set to what you want
#define DATA_PIN pin_yy //again set to what you want
void set_volume(unsigned int8 att, int1 chan, int1 both_flag)
{
int16 val=0x60; //Preload the upper two 1's
int8 ctr;
int16 mask=1; //mask bit
output_low(CLOCK_PIN); //ideally set this low in your initialisation
if (att1>83)
att1=83;
val |= ((21 - (att / 4L)) << 2); // ATT1: coarse attenuator, steps of
//-4dB
val |= ((3 - (att % 4L)) << 7); // ATT2: fine attenuator, steps
//of -1dB) - Note the L here, needed so the value gets extended to
//an int16 for the rotation.
if (chan)
bit_set(val,0); //channel 0/1 selection
if (both_flag)
bit_set(val,1); //If this is set will write both channels at once
for (ctr=0;ctr<11;ctr++)
{
if(mask & val)
output_high(DATA_PIN);
else
output_low(DATA_PIN);
delay_us(1);
output_high(CLOCK_PIN); //Latch the bit out.
mask*=2;
output_low(DATA_PIN);
delay_us(1);
if (ctr!=10)
output_low(DATA_PIN);
output_low(CLOCK_PIN);
delay_us(1);
}
}
|
I send the channel and both_flag each as one bit values, so no need
to test for these being >1. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|