0.3.0 M62429

This commit is contained in:
rob tillaart 2022-01-05 16:44:57 +01:00
parent 8accc98321
commit 28303eac11
8 changed files with 204 additions and 26 deletions

View File

@ -2,7 +2,7 @@
// FILE: M62429.cpp
// AUTHOR: Rob Tillaart
// PURPOSE: Arduino library for M62429 volume control IC
// VERSION: 0.2.2
// VERSION: 0.3.0
// HISTORY: See M62429.cpp2
// URL: https://github.com/RobTillaart/M62429
@ -12,6 +12,7 @@
// 0.2.1 2020-12-30 add Arduino-CI + unit test
// 0.2.2 2021-05-27 fix library.properties
// 0.2.3 2021-12-21 update library.json, license, readme, minor edits
// 0.3.0 2021-12-30 fix #4 incomplete protocol
#include "M62429.h"
@ -51,7 +52,7 @@ int M62429::setVolume(uint8_t channel, uint8_t volume)
if (channel == 0) _vol[0] = volume;
if (channel == 1) _vol[1] = volume;
if (channel == 2) _vol[0] = _vol[1] = volume;
return 0;
return M62429_OK;
}
@ -104,32 +105,39 @@ void M62429::muteOff()
// attn = 0, 3..87
void M62429::_setVolume(uint8_t channel, uint8_t attn)
{
uint16_t databits = 0xFE00; // latch bits
databits |= (attn & 0x007C);
databits |= ((attn & 0x03) << 7);
uint16_t databits = 0xFE00; // D10 - D9 latch bits
databits |= ((attn & 0x03) << 7); // D8 - D7
databits |= (attn & 0x007C); // D6 - D2
// channel == 2 -> both 0x00 is default
if (channel == 0) databits |= 0x03; // 11
if (channel == 1) databits |= 0x02; // 01
if (channel == 0) databits |= 0x03; // D0 - D1
if (channel == 1) databits |= 0x02; // D0 - D1
for (uint16_t mask = 1; mask < 0x0200; mask <<= 1)
// write D0 - D9
for (uint16_t mask = 1; mask < 0x0400; mask <<= 1)
{
digitalWrite(_data, databits & mask);
digitalWrite(_clock, HIGH);
// Note that if clock pulses are long enough the data pulses are automatically too.
// Note if _clock pulses are long enough, _data pulses are too.
if (M62429_CLOCK_DELAY > 0) delayMicroseconds(M62429_CLOCK_DELAY);
digitalWrite(_data, LOW);
digitalWrite(_clock, LOW);
if (M62429_CLOCK_DELAY > 0) delayMicroseconds(M62429_CLOCK_DELAY);
}
// Last latch bit must be high
// Send D10 HIGH bit (Latch signal)
digitalWrite(_data, HIGH);
digitalWrite(_clock, HIGH);
if (M62429_CLOCK_DELAY > 0) delayMicroseconds(M62429_CLOCK_DELAY);
// _data is already high
// latch signal requires _clock low before _data
// make _data dummy write to keep timing constant
digitalWrite(_data, HIGH);
digitalWrite(_clock, LOW);
if (M62429_CLOCK_DELAY > 0) delayMicroseconds(M62429_CLOCK_DELAY);
digitalWrite(_data, LOW);
if (M62429_CLOCK_DELAY > 0) delayMicroseconds(M62429_CLOCK_DELAY);
}

View File

@ -3,7 +3,7 @@
// FILE: M62429.h
// AUTHOR: Rob Tillaart
// PURPOSE: Arduino library for M62429 volume control IC
// VERSION: 0.2.3
// VERSION: 0.3.0
//
// HISTORY: See M62429.cpp
// URL: https://github.com/RobTillaart/M62429
@ -12,7 +12,7 @@
#include "Arduino.h"
#define M62429_VERSION (F("0.2.3"))
#define M62429_VERSION (F("0.3.0"))
// minimum pulse width CLOCK = 1.6 us (datasheet);
@ -20,16 +20,17 @@
// Note that if clock pulses are long enough the data pulses are too.
#ifndef M62429_CLOCK_DELAY
#ifdef __AVR__
#define M62429_CLOCK_DELAY 0
#define M62429_CLOCK_DELAY 0
#else
#define M62429_CLOCK_DELAY 2
#define M62429_CLOCK_DELAY 2
#endif
#endif
// ERROR CODES
#define M62429_MUTED -1
#define M62429_CHANNEL_ERROR -10
#define M62429_OK 0
#define M62429_MUTED -1
#define M62429_CHANNEL_ERROR -10
class M62429
@ -62,3 +63,4 @@ private:
// -- END OF FILE --

View File

@ -54,16 +54,49 @@ See examples
## Future
- Control multiple M62429 IC's with one class. This could work with one
shared dataPin and one clockPin per IC. An idea might be to use one PCF8575
to have 1 dataPin and 15 clockPins. That would allow for 15 stereo channels
or 30 mono channels. Runtime configuration mono / stereo would be cool.
- model with one **volume(0..100%)** and one **balance(-100..100)**.
#### Mixer
- Control multiple M62429 IC's
- One shared dataPin and clockPin per IC.
- use a PCF8574 / PCF8575 as selector
- would allow for 16 stereo or 32 mono channels.
Runtime configuration mono / stereo would be cool.
```
PCF8574 or PCF8575 is used as device selector
AND port takes DATA and CLOCK to right M62429
identical schema for all 8/16 ports
PCF8575 AND M62429
+---------+ +---+ +---------+
| |=======+======| & |==========| data |
| | +===|======| | | |
- I2C - | | | | +---+ | |
| | | | | |
| | | | +---+ | |
| | | +======| & |==========| clock |
| | | +====| | | |
| | | | +---+ | |
+---------+ | | +---------+
| |
DATA ==============+ |
CLOCK ====================+
```
#### Other
- model with one **volume(0..100%)** and one **balance(-100..100)** == **pan()**.
Also a **left()** and **right()** incremental balance might be added.
This could work better than 2 separate volume channels.
- change **getVolume(both)** to return max of the two channels?
- **muteOff()** should increase gradually.
- **Mute()** could be per channel, default = both / all.
- **mute50()** reduces levels with 50% (rounded down?).
- find a big can filled with time ...
- optimize when volume is already set?
- e.g. average function.
- muteOff will fail ? investigate
**wont**
- **muteOff()** should increase gradually. takes too much blocking time.

View File

@ -0,0 +1,110 @@
//
// FILE: M62429_performance.ino
// AUTHOR: Rob Tillaart
// PURPOSE: demo volume IC FM62429
// DATE: 2021-12-30
#include "M62429.h"
uint32_t start, stop;
M62429 AMP;
void setup()
{
Serial.begin(115200);
Serial.println(__FILE__);
Serial.println();
Serial.print("M62429_VERSION: ");
Serial.println(M62429_VERSION);
AMP.begin(4, 5);
delay(100);
start = micros();
AMP.setVolume(0, 10);
stop = micros();
Serial.print("setVolume: \t");
Serial.println(stop - start);
delay(100);
start = micros();
AMP.setVolume(0, 10);
stop = micros();
Serial.print("setVolume: \t");
Serial.println(stop - start);
delay(100);
start = micros();
AMP.setVolume(0, 100);
stop = micros();
Serial.print("setVolume: \t");
Serial.println(stop - start);
delay(100);
start = micros();
AMP.setVolume(0, 100);
stop = micros();
Serial.print("setVolume: \t");
Serial.println(stop - start);
delay(100);
start = micros();
volatile uint8_t x = AMP.getVolume(0);
stop = micros();
Serial.print("getVolume: \t");
Serial.println(stop - start);
delay(100);
AMP.setVolume(2, 0);
start = micros();
AMP.incr();
stop = micros();
Serial.print("increment: \t");
Serial.println(stop - start);
delay(100);
AMP.setVolume(2, 0);
start = micros();
AMP.decr();
stop = micros();
Serial.print("decrement: \t");
Serial.println(stop - start);
delay(100);
AMP.setVolume(2, 10);
start = micros();
AMP.muteOn();
stop = micros();
Serial.print("muteOn: \t");
Serial.println(stop - start);
delay(100);
start = micros();
AMP.muteOff();
stop = micros();
Serial.print("muteOff: \t");
Serial.println(stop - start);
delay(100);
AMP.setVolume(0, 10);
AMP.setVolume(1, 20);
start = micros();
AMP.average();
stop = micros();
Serial.print("average: \t");
Serial.println(stop - start);
delay(100);
Serial.println("\nDone...");
}
void loop()
{
}
// -- END OF FILE --

View File

@ -0,0 +1,15 @@
...\M62429_performance.ino
M62429_VERSION: 0.3.0
setVolume: 196
setVolume: 196
setVolume: 196
setVolume: 196
getVolume: 4
increment: 388
decrement: 392
muteOn: 4
muteOff: 388
average: 396

View File

@ -15,7 +15,7 @@
"type": "git",
"url": "https://github.com/RobTillaart/M62429.git"
},
"version": "0.2.3",
"version": "0.3.0",
"license": "MIT",
"frameworks": "*",
"platforms": "*",

View File

@ -1,5 +1,5 @@
name=M62429
version=0.2.3
version=0.3.0
author=Rob Tillaart <rob.tillaart@gmail.com>
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
sentence=Arduino library for M62429 volume control IC

View File

@ -105,6 +105,16 @@ unittest(test_all)
assertEqual(10, AMP.getVolume(0));
for (int i = 0; i < 5; i++) AMP.decr();
assertEqual(5, AMP.getVolume(0));
fprintf(stderr, "\naverage\n");
AMP.setVolume(0, 10);
AMP.setVolume(1, 20);
assertEqual(10, AMP.getVolume(0));
assertEqual(20, AMP.getVolume(1));
AMP.average();
assertEqual(15, AMP.getVolume(0));
assertEqual(15, AMP.getVolume(1));
}