Bit-Banging UNI/O Bus with Arduino Uno [Failing]

Hey Guys!

I just managed to set everything up to bit-bang my UNI/O driven EEPROM. Sadly I have not managed to get it to work properly.

Some information for you if you want to help out:

The Datasheet of my EEPROM The UNI/O Bus Spec sheet

What I did so far?

I was about to do some Adress Polling |500x197

It is a way I can actually debug stuff since I receive a SAK if the device is adressable. I've setup my code here to do the first example of the address polling. After sending the NoMAK after the address byte I was about to receive a SAK. But I only receive NoSAK the whole time. My problem is now that I can't figure out the error source because debugging seems pretty tricky here. Rather impossible for me. I'm about to receive a Oszilloskop in a few days to at least check out my frequencies. But to be honest I'm sure my frequencies won't be the issue here because its all about a minimum of µs and I cleared all doubts by adding an offset of 5µs at every time constant.

Maybe you guys have an idea where the issue may be. I really want to finish this tryout and don't want to give up.

#define TSTBY 605 // StandBy-Pulse 600µs + 5µs offset
#define TSS 15 // StartHeader setup time 10µs + 5µs offset
#define THDR 10 // StartHeader low pulse time 5µs + 5µs offset
#define TE 15 // BitPeriod time 10µs + 5µs offset

#define BUSPIN 9 // Pin to communicate with set to 9

int fstEdgeSample = 0;
int sndEdgeSample = 0;

void setup()
{
    Serial.begin(9600);
    pinMode(BUSPIN, OUTPUT);
    digitalWrite(BUSPIN, LOW);
    StandByPulse();
    StartHeaderPulse();
    MAK();
    if (isSAK()) Serial.println("SAK"); else Serial.println("NoSAK");
    AdressPulse();
    NoMAK();
    if (isSAK()) Serial.println("SAK"); else Serial.println("NoSAK");
}

void loop()
{

  /* add main program code here */

}

void BitOne()
{
    digitalWrite(BUSPIN, LOW);
    delayMicroseconds(TE / 2); 
    digitalWrite(BUSPIN, HIGH);
    delayMicroseconds(TE / 2); 
}

void BitZero()
{
    digitalWrite(BUSPIN, HIGH);
    delayMicroseconds(TE / 2);
    digitalWrite(BUSPIN, LOW);
    delayMicroseconds(TE / 2);
}

void MAK()
{
    BitOne();
}

void NoMAK()
{
    BitZero();
}

void TransmitByte(uint8_t value)
{
    if (value & 0x80) BitOne(); else BitZero();
    if (value & 0x40) BitOne(); else BitZero();
    if (value & 0x20) BitOne(); else BitZero();
    if (value & 0x10) BitOne(); else BitZero();
    if (value & 0x08) BitOne(); else BitZero();
    if (value & 0x04) BitOne(); else BitZero();
    if (value & 0x02) BitOne(); else BitZero();
    if (value & 0x01) BitOne(); else BitZero();
}


void StandByPulse()
{
    digitalWrite(BUSPIN, HIGH); // Write high digital signal
    delayMicroseconds(TSTBY); // let standby-pulse time pass
}

void StartHeaderPulse()
{
    digitalWrite(BUSPIN, LOW); // High to Low transition for THDR
    delayMicroseconds(THDR); // THDR Time

    TransmitByte(0b01010101);
}

void AdressPulse()
{
    TransmitByte(0b10100000);
}

bool isSAK()
{
    pinMode(BUSPIN, INPUT);
    delayMicroseconds(TE / 4); // Trimmed-Bit-Period
    fstEdgeSample = digitalRead(BUSPIN);
    delayMicroseconds(TE / 2); // Trimmed-Bit-Period
    sndEdgeSample = digitalRead(BUSPIN);
    delayMicroseconds(TE / 4); // Trimmed-Bit-Period
    pinMode(BUSPIN, OUTPUT);

    if (fstEdgeSample == LOW && sndEdgeSample == HIGH)
        return true;
    else
        return false;
}

That is not easy at all, the clock can be 10us to 100us.
A digitalWrite() is already 5us, and a digitalRead() takes 3.5us.

The OneWire, DHT11/DHT22, NeoPixel, and others, they all use a single wire bit-banging timing based protocol.
Did you see the timing section of the NeoPixel library ?

Are you sure you are the first person to implement UNI/O for Arduino ?
Is this helpful : GitHub - sde1000/NanodeUNIO: Driver for Microchip UNI/O devices on Nanode (eg. the MAC address chip)

Hey there!

No I'm not the first person :D But that's also not my goal. I want to learn the mechanics to the core. And therefore I just want to do it like it would be a new thing ;)

I see the issues with the timing here. Where did you have the µs-values for a digitalWrite() and a digitalRead() ?

http://forum.arduino.cc/index.php?topic=326944.0 http://playground.arduino.cc/Main/ShowInfo

Thanks for the informations!

I just figured out theres a PortRegister Constant which I can manipulate to get faster results:

https://www.arduino.cc/en/Reference/PortManipulation