system
November 7, 2013, 7:13am
1
Hi, All.
I wrote a library for programming AD8555/8556 op-amps from Analog Devices. It works fine with AD8556, but I don't have a AD8555 chip around.
Could someone test it with AD8555 at least in simulation mode?
link to github: GitHub - ivolkov/AD8555: AD8555 library for Arduino IDE
Hi, thanks for sharing,
I see a number of improvements in the lib, I will patch and post asap. Don't have a chip to test BTW.
I'll be back
changed datatype to uint8_t where possible -> simplified the code in several places
added some loops to minimize footprint
added a function to replace repeating code
added header with version info ++
TODO replace some magic numbers (0b00 etc) with #defines
TODO look at the function names if they can be more descriptive SendField0 --> senStartBits()
//
// FILE: AD8555.cpp
// AUTHOR:
// VERSION: 0.1.01
// DATE: 2013-11-07
// PURPOSE:
//
// HISTORY:
// 0.1.00 - 2011-11-07 initial version
// 0.1.01 - 2013-11-07 refactored
//
// Released to the public domain
//
#include "AD8555.h"
AD8555::AD8555(uint8_t outputPin)
{
outPin = outputPin;
digitalWrite(outPin, LOW); // first low then outputmode prevents a possible small HIGH spike.
pinMode(outPin, OUTPUT);
}
bool AD8555::setSecondStageGain(uint8_t value)
{
if (value > 7) return false;
SSG = value;
return true;
}
bool AD8555::setFirstStageGain(uint8_t value)
{
if (value > 127) return false;
FSG = value;
return true;
}
bool AD8555::setOffset(uint8_t value)
{
OFS = value;
return true;
}
void AD8555::simulate()
{
sendFields(0b01, 0b00, SSG);
sendFields(0b01, 0b01, FSG);
sendFields(0b01, 0b10, OFS);
}
//
// NEW FUNCTION
//
void AD8555::sendFields(uint8_t mode, uint8_t func, uint8_t value)
{
sendField0(); // start packet
sendField1(mode);
sendField2(func);
sendField3();
sendField4(value);
sendField5(); // stop packet
}
void AD8555::program()
{
uint8_t par;
for (uint8_t i = 0 ; i < 8 ; i++)
{
if (((SSG >> i) & 1) == 1)
{
par = (1 << i);
blowSSGFuse(par);
}
}
for (uint8_t i = 0 ; i < 8 ; i++)
{
if (((FSG >> i) & 1) == 1)
{
par = (1 << i);
blowFSGFuse(par);
}
}
for (uint8_t i = 0 ; i < 8 ; i++)
{
if (((OFS >> i) &1) == 1)
{
par = (1 << i);
blowOFSFuse(par);
}
}
blowMSF();
}
void AD8555::blowSSGFuse(unsigned char Value)
{
sendFields(0b10, 0b00, Value);
delay(1);
}
void AD8555::blowFSGFuse(unsigned char Value)
{
sendFields(0b10, 0b01, Value);
delay(1);
}
void AD8555::blowOFSFuse(unsigned char Value)
{
sendFields(0b10, 0b10, Value);
delay(1);
}
void AD8555::blowMSF()
{
sendFields(0b10, 0b11, 0b00000001);
delay(1);
}
void AD8555::sendField0()
{
sendBit(1);
for (uint8_t i=0; i<10; i++) sendBit(0);
sendBit(1);
}
void AD8555::sendField1(uint8_t value)
{
sendBit((value >> 1) & 1);
sendBit(value & 1);
}
void AD8555::sendField2(uint8_t value)
{
sendBit((value >> 1) & 1);
sendBit(value & 1);
}
void AD8555::sendField3()
{
sendBit(1);
sendBit(0);
}
void AD8555::sendField4(uint8_t value)
{
uint8_t i = 8;
do
{
i--;
sendBit((value >> i) & 1);
}
while(i > 0);
}
void AD8555::sendField5()
{
sendBit(0);
for (uint8_t i=0; i<10; i++) sendBit(1);
sendBit(0);
}
void AD8555::sendBit(bool value)
{
if (value) send1();
else send0();
}
void AD8555::send0()
{
digitalWrite(outPin, HIGH);
digitalWrite(outPin, LOW);
delayMicroseconds(500); // delay(0) is no delay...
}
void AD8555::send1()
{
digitalWrite(outPin, HIGH);
// why delay(0) that makes no sense ... use delayMicroseconds() to time very small units
delayMicroseconds(500);
digitalWrite(outPin, LOW);
delayMicroseconds(500);
}
have a look
system
November 7, 2013, 5:05pm
3
Well that will be awesome. Opensource in action, whoohoo
you need to adapt the .h file to get it to work of course
if there are questions just ask
(we will show the world that Russia and the Netherlands cooperate (more than 400yrs!)
PS, you have to check the delay(0) remark in the code.
system
November 8, 2013, 6:43am
5
Thanks! I've applied your suggestions to 'dev' branch. To be tested and merged to 'master' branch. It's always good to have someone to review your code.
robtillaart:
PS, you have to check the delay(0) remark in the code.
Yeah... AD8555 may be nasty when it's come to timings. +/- 10 us may actually brick this device in some cases and I wasn't aware that Arduino has delayMicroseconds function (silly me) so I use this stupid delay(0) code. Thanks for pointing out that moment.
small issue
if (((SSG >> i) & 1) == 1)
can be written as
if ( (SSG >> i) & 1)
as every value not 0 is considered true. It is a well known practice in C.
With respect to delay(1), you should note that delayMIcros(1000) is more accurate than delay(1).
system
November 8, 2013, 1:23pm
8
So far, I've checked all timings and merged changes to master branch of repository GitHub - ivolkov/AD8555: AD8555 library for Arduino IDE .
Still hope someone will test this library to work with AD8555 chip (not AD8556). Have no idea why it wouldn't do the job but just to be sure.
Looks good!
another tip
void AD8555::sendMode(uint8_t value)
{
sendBit((value >> 1) & 1);
sendBit(value & 1);
}
void AD8555::sendFunc(uint8_t value)
{
sendBit((value >> 1) & 1);
sendBit(value & 1);
}
void AD8555::sendDummy()
{
sendBit(1);
sendBit(0);
}
these can be replaced by one function, reduces the footprint of the library.
#define DUMMY 0b00000010
void AD8555::send(uint8_t value)
{
sendBit((value >> 1) & 1);
sendBit(value & 1);
}
Finally you could add a link in the header to this thread so people can discuss the library.
system
November 9, 2013, 11:32am
10
robtillaart:
Finally you could add a link in the header to this thread so people can discuss the library.
Good idea.
robtillaart:
these can be replaced by one function, reduces the footprint of the library.
Thanks, fixed.
BTW are you using static code analyzer or some other refactoring software?
No, an eye for patterns, paper and pen,experience and a lot of trial and error.
I like optimizing SW and the constraints of an Arduino "scream" for SW balanced between functionality and code size and performance.