Pages: [1]   Go Down
Author Topic: AD8555 library testing  (Read 1275 times)
0 Members and 1 Guest are viewing this topic.
Russia
Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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: https://github.com/ivolkov/AD8555
« Last Edit: November 08, 2013, 01:32:23 am by Ilya Volkov » Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 212
Posts: 13531
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 smiley-wink

+ 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()
Code:
//
//    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
« Last Edit: November 07, 2013, 12:13:05 pm by robtillaart » Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Russia
Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Well that will be awesome. Opensource in action, whoohoo  smiley
Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 212
Posts: 13531
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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!) smiley-wink

PS, you have to check the delay(0) remark in the code.
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Russia
Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.

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.
Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 212
Posts: 13531
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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).

Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Russia
Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Fixed!
Logged

Russia
Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

So far, I've checked all timings and merged changes to master branch of repository https://github.com/ivolkov/AD8555.

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.
Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 212
Posts: 13531
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Looks good!

another tip
Code:
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.

Code:
#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.
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Russia
Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Finally you could add a link in the header to this thread so people can discuss the library.
Good idea.

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?
Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 212
Posts: 13531
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Pages: [1]   Go Up
Jump to: