Post Go back to editing

Acknowledge from MAX2112

Category: Datasheet/Specs
Product Number: MAX2112

#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>

#define SDA_PIN PD2
#define SCL_PIN PD3

// --- I²C macros (open-drain style) ---
#define SDA_LOW()    { DDRD |=  (1<<SDA_PIN); PORTD &= ~(1<<SDA_PIN); }  // drive 0
#define SDA_RELEASE(){ DDRD &= ~(1<<SDA_PIN); }                          // release line

#define SCL_LOW()    { DDRD |=  (1<<SCL_PIN); PORTD &= ~(1<<SCL_PIN); }  // drive 0
#define SCL_HIGH()   { DDRD |=  (1<<SCL_PIN); PORTD |=  (1<<SCL_PIN); }  // drive 1

#define SDA_READ()   (PIND & (1<<SDA_PIN))  // read SDA state
#define I2C_DELAY()  _delay_us(5)           // ~100 kHz I²C

// --- I²C functions ---
void i2c_init(void) {
    SDA_RELEASE();
    SCL_HIGH();
}

void i2c_start(void) {
    SDA_RELEASE(); SCL_HIGH(); I2C_DELAY();
    SDA_LOW();     I2C_DELAY();
    SCL_LOW();     I2C_DELAY();
}

void i2c_stop(void) {
    SDA_LOW();     I2C_DELAY();
    SCL_HIGH();    I2C_DELAY();
    SDA_RELEASE(); I2C_DELAY();
}

// Write byte and return ACK/NACK
uint8_t i2c_write(uint8_t data) {
    for (uint8_t i=0; i<8; i++) {
        if (data & 0x80) SDA_RELEASE(); else SDA_LOW();
        I2C_DELAY();

        SCL_HIGH(); I2C_DELAY();
        SCL_LOW();  I2C_DELAY();

        data <<= 1;
    }

    // ACK cycle
    SDA_RELEASE();        // release SDA for slave
    I2C_DELAY();

    SCL_HIGH();           // pulse SCL for ACK
    I2C_DELAY();
    uint8_t ack = (SDA_READ()==0);  // read SDA while high
    SCL_LOW();

    return ack;  // 1=ACK, 0=NACK
}

int main(void) {
    i2c_init();

    while (1) {
        i2c_start();
        uint8_t ack = i2c_write(0xC0);   // MAX2112 slave address (write)
        i2c_stop();

        // Here ack variable tells if MAX2112 pulled SDA low
        // Connect logic analyzer to SDA/SCL to see the ACK bit

        _delay_ms(500);
    }
}

I am programming my ATMEGA32A 16 MHz external clock to write address C0 in MAX2112, but I am not getting any acknowledge bit or command from MAX2112, meaning at the 9th pulse of SCL Clock Signal I should get 0 on SDA but there is no Low or 0 there is High, what should be the solution?