Hot!No ack from EERAM 47C04

Author
xiaomc
New Member
  • Total Posts : 1
  • Reward points : 0
  • Joined: 2017/10/08 22:49:50
  • Location: 0
  • Status: offline
2017/11/12 21:00:44 (permalink)
0

No ack from EERAM 47C04

I don't know if it is the right place to post this question, move it if need.
 
I want to use 47C04 as the share RAM among 3 arduino nano boards to replace the IIC bus communication.
And I got it after 1 week from Microchip.
But I cant get the ack rightly.
 
The pin set:
    Vcc -> Vcc of NANO board
    Vss/A2/A1 -> Vss of NANO board
    HS -> float
    Vcap -> 220uf (no smaller one)
    SCL/SDA -> digital pin of NANO
I don't want to use the interrupt mode, plain code is enough:
 


void EERAM47C04ByIIC::iic_start(void) {
    SDAHIGH;
    SCLHIGH;
    KEEP_STABLE;
    SDALOW;
    KEEP_STABLE;
    SCLLOW; //hold the bus
}

void EERAM47C04ByIIC::iic_stop(void) {
    SDALOW;
    SCLHIGH;
    KEEP_STABLE;
    SDAHIGH;
    KEEP_STABLE;
    //SCLLOW; //to keep the bus free(SDA = SCL = HIGH), should not pull low
}

void EERAM47C04ByIIC::iic_ack(void) {
    SDALOW;
    SCLHIGH;
    KEEP_STABLE;
    SCLLOW; //hold the bus
}

void EERAM47C04ByIIC::iic_noack(void) {
    SDAHIGH;
    SCLHIGH;
    KEEP_STABLE;
    //SCLLOW; //if reply with noack, we means don't use it anymore, so free it
}

bool EERAM47C04ByIIC::iic_send_byte(unsigned char b) {
    for(unsigned char i = 0; i < 8; i++) {
        if(!(b & 0x80)) {SDALOW;} else SDAHIGH;
        SCLHIGH;
        KEEP_STABLE;
        SCLLOW;
        b <<= 1;
    }
      
    SDAHIGH;
    SCLHIGH;
    //KEEP_STABLE; //wait for ack send out by slave
    SCLLOW;
    bool ack = (digitalRead(sdaPin)==HIGH)?false:true;
      
    return ack;
}

unsigned char EERAM47C04ByIIC::iic_rcv_byte(void) {
    unsigned char i,a,temp = 0;
      
    SDAHIGH;
    for(i = 0; i < 8; i++) {
        SCLLOW;
        KEEP_STABLE;
        SCLHIGH;
        if(digitalRead(sdaPin)==HIGH) { a = 1; } else a = 0;
          
        temp |= (a << (7 - i));
        //KEEP_STABLE; //need not? for there are many cycles passed since SCLHIGH
    }
      
    SCLLOW; //hold bus
    return temp;
}

 
I dont know why can't upload files,copy here for reference:
 
.h:
#ifndef EERAM_47C04_IIC_H
#define EERAM_47C04_IIC_H
#include <arduino.h>

extern void __builtin_avr_delay_cycles(unsigned long );
#define delay_us(x) __builtin_avr_delay_cycles((unsigned long)(F_CPU*(double)x/1000000.0))
//#define delay_ms(x) __builtin_avr_delay_cycles((long)(F_CPU*(double)x/1000.0))
#define KEEP_STABLE {delay_us(1);}

#define sdaPin 7
#define sclPin 8
#define SDAHIGH {digitalWrite(sdaPin,HIGH);}
#define SDALOW {digitalWrite(sdaPin,LOW);}
#define SCLHIGH {digitalWrite(sclPin,HIGH);}
#define SCLLOW {digitalWrite(sclPin,LOW);}
const unsigned char EERAMAddressWrite = 0xA0;
const unsigned char EERAMAddressRead = 0xA1;
//const unsigned char EERAMRegisterWrite = 0x30;
//const unsigned char EERAMRegisterRead = 0x31;

#define ADDRESS_START 1
#define ADDRESS_CHANGED_SIGN 0

class EERAM47C04ByIIC {
    private:
        inline bool iic_free(void) { return ((digitalRead(sdaPin)==HIGH) && (digitalRead(sclPin)==HIGH)); } ;
        void iic_start(void) ;
        void iic_stop(void);
        void iic_ack(void);
        void iic_noack(void);
        bool iic_send_byte(unsigned char byte);
        unsigned char iic_rcv_byte(void);

        bool write2Bytes(unsigned char idx,unsigned int value,bool isInt);
        bool read2Bytes(unsigned int address,unsigned int* value,bool isInt);
    public:
        EERAM47C04ByIIC(){
            pinMode(sdaPin,OUTPUT);
            pinMode(sclPin,OUTPUT);
            SDAHIGH ;
            SCLHIGH ;
        };
        
        inline bool writeInt(unsigned char idx,unsigned int value);
        inline bool writeByte(unsigned char idx,unsigned char value);
        inline bool readInt(unsigned char idx,unsigned int* value);
        inline bool readByte(unsigned char idx,unsigned int* value);
        bool changed(void);
};

#endif

.cpp:
#include "eeram47C04ByIIC.h"
#include <arduino.h>

bool EERAM47C04ByIIC::changed(void){
    unsigned int value = 0;
    bool ret = false;
    if( read2Bytes(ADDRESS_CHANGED_SIGN,&value,false))
        if(value>0) ret = true;
    iic_noack();
    iic_stop();
    return ret;
}

bool EERAM47C04ByIIC::readByte(unsigned char idx,unsigned int* value){
    return read2Bytes((ADDRESS_START + idx * 2),value,false);
}

bool EERAM47C04ByIIC::readInt(unsigned char idx,unsigned int* value){
    return read2Bytes((ADDRESS_START + idx * 2),value,true);
}

bool EERAM47C04ByIIC::read2Bytes(unsigned int address,unsigned int* value,bool isInt){
    bool ret = false;
    
    if(!iic_free()) {Serial.println("iic not free"); return ret;}
    iic_start();
    if(!iic_send_byte(EERAMAddressRead)) {Serial.println("iic send ic address falied"); iic_stop();return ret;}
    if(!iic_send_byte(byte(address >> 8))) {Serial.println("iic send ram H address falied"); iic_stop();return ret;}
    if(!iic_send_byte(byte(address))) {Serial.println("iic send ram L address falied"); iic_stop();return ret;}
    
    *value = iic_rcv_byte();
    if(isInt){
        *value <<= 8; //MSB
        iic_ack();
        *value |= iic_rcv_byte();
    }
    //ack or P sent in top function
    ret = true;
    return ret;
}

inline bool EERAM47C04ByIIC::writeInt(unsigned char idx,unsigned int value){
    return write2Bytes(idx,value,true);
}

inline bool EERAM47C04ByIIC::writeByte(unsigned char idx,unsigned char value){
    return write2Bytes(idx,value,false);
}

bool EERAM47C04ByIIC::write2Bytes(unsigned char idx,unsigned int value,bool isInt){
    bool ret = false;
    unsigned int start = ADDRESS_START + idx * 2;
    if(!iic_free()) {Serial.println("iic not free"); return ret;}
    iic_start();
    
    if(!iic_send_byte(EERAMAddressWrite)) {Serial.println("iic send ic address falied"); iic_stop();return ret;}
    if(!iic_send_byte(byte(start >> 8))) {Serial.println("iic send ram H address falied"); iic_stop();return ret;} //MSB
    if(!iic_send_byte(byte(start))) {Serial.println("iic send ram L address falied"); iic_stop();return ret;} //LSB
    if(isInt){
        if(!iic_send_byte(byte(value >> 8))) {Serial.println("iic send ram H address falied"); iic_stop();return ret;} //MSB
    }
    if(!iic_send_byte(byte(value))) {Serial.println("iic send value address falied"); iic_stop();return ret;} //LSB
    
    ret = true;
    return ret;
}


void EERAM47C04ByIIC::iic_start(void) {
    SDAHIGH;
    SCLHIGH;
    KEEP_STABLE;
    SDALOW;
    KEEP_STABLE;
    SCLLOW; //hold the bus
}

void EERAM47C04ByIIC::iic_stop(void) {
    SDALOW;
    SCLHIGH;
    KEEP_STABLE;
    SDAHIGH;
    KEEP_STABLE;
    //SCLLOW; //to keep the bus free(SDA = SCL = HIGH), should not pull low
}

void EERAM47C04ByIIC::iic_ack(void) {
    SDALOW;
    SCLHIGH;
    KEEP_STABLE;
    SCLLOW; //hold the bus
}

void EERAM47C04ByIIC::iic_noack(void) {
    SDAHIGH;
    SCLHIGH;
    KEEP_STABLE;
    //SCLLOW; //if reply with noack, we means don't use it anymore, so free it
}

bool EERAM47C04ByIIC::iic_send_byte(unsigned char b) {
    for(unsigned char i = 0; i < 8; i++) {
        if(!(b & 0x80)) {SDALOW;} else SDAHIGH;
        SCLHIGH;
        KEEP_STABLE;
        SCLLOW;
        b <<= 1;
    }
      
    SDAHIGH;
    SCLHIGH;
    //KEEP_STABLE; //wait for ack send out by slave
    SCLLOW;
    bool ack = (digitalRead(sdaPin)==HIGH)?false:true;
      
    return ack;
}

unsigned char EERAM47C04ByIIC::iic_rcv_byte(void) {
    unsigned char i,a,temp = 0;
      
    SDAHIGH;
    for(i = 0; i < 8; i++) {
        SCLLOW;
        KEEP_STABLE;
        SCLHIGH;
        if(digitalRead(sdaPin)==HIGH) { a = 1; } else a = 0;
          
        temp |= (a << (7 - i));
        //KEEP_STABLE; //need not? for there are many cycles passed since SCLHIGH
    }
      
    SCLLOW; //hold bus
    return temp;
}

#1

1 Reply Related Threads

    bp2012
    Junior Member
    • Total Posts : 16
    • Reward points : 0
    • Joined: 2012/08/22 12:59:18
    • Location: 0
    • Status: offline
    Re: No ack from EERAM 47C04 2017/11/14 16:08:58 (permalink)
    4 (1)
    Hello,
    I understand most of your description, please correct me where I misunderstand below.
     
    You are using multiple Arduino nano's to talk to one EERAM device, so this is a multi-master IIC situation.
    You are using software IIC communication, instead of the Arduino Wire.h library.
    I see you have set the digital pins to change states, I did not see if you configured those to communicate as open-drain, this would be required for IIC, especially for multi-master, but also just to receive data and ACK signals back from the EERAM.
     
    You did not mention the value of the SDA and SCL pullup resistors.  These are necessary for open-drain operation. A value from 1K to 10K is typical, the lower values for higher speed (see EERAM datasheet).
     
    I have used Arduino to talk to EERAM, using the Wire.h (TWI AVR equivalent to IIC communications), and it does work very nicely as expected.  I can send sample codes of that if you like.  The library does correctly configure the pins for open-drain, and so it can work in this sort of situation.
     
    Do you have success using any other IIC slave device?  If so, then I would assume you have experience making it work and the issues above are not a problem.  If not, I would recommend confirming the open-drain configuration on a single Arduino talking to the EERAM, and take waveform images on a digital scope.  Those would be valuable to share here on the forum, and they may help you to compare to the waveforms in the datasheet to see how they look.
     
    Another issue is the very large Vcap capacitor you have.  This is about 10X larger than the normal recommended size, so this will take longer to charge up.  If you are trying to check for an ACK immediately after power-up, you may have to wait longer for this capacitor to charge compared to a smaller cap, as the Vcap voltage has to cross the Vtrip point before the device can ACK any communication.
     
    There are a few application notes on using the EERAM on the Microchip website, those would be valuable as well.
     
    [Bp)
    #2
    Jump to:
    © 2018 APG vNext Trial Version 4.5