I want to use the STM32 microcontroller to configure the ADAU1450 DSP registers using I2C. I have tried to follow the steps for configuring this DSP registers as explained in Table 27 of the ADAU1450/1452 datasheet, but I am not getting any response from the ADAU1450. I don't know where I could be going wrong.
here are my header and source files...
#ifndef I2C_H_
#define I2C_H_
#include "stm32.h"
#include <stdint.h>
void I2C1_Init(void);
void I2C1_Write(uint8_t saddr, uint16_t reg, const uint8_t *data, uint16_t len);
void I2C1_Read(uint8_t saddr, uint16_t reg, uint8_t *data, uint16_t len);
#include "i2c.h"
#define I2C_SPEED 40 // ~100kHz for 8 MHz APB1
#define I2C_TRISE 9
#define I2C1_EN (1U << 21)
#define GPIOB_EN (1U << 3)
void I2C1_Init(void)
{
RCC->APB2ENR |= GPIOB_EN;
RCC->APB1ENR |= I2C1_EN;
// PB6, PB7 Alternate function open-drain
GPIOB->CRL &= ~((0xF << 24) | (0xF << 28));
GPIOB->CRL |= ((0xB << 24) | (0xB << 28)); // MODE=11 (50MHz), CNF=10 (AF open-drain)
// Software reset
I2C1->CR1 |= (1 << 15);
I2C1->CR1 &= ~(1 << 15);
I2C1->CR2 = 8; // APB1 = 8 MHz
I2C1->CCR = I2C_SPEED;
I2C1->TRISE = I2C_TRISE;
I2C1->CR1 |= (1 << 0); // Enable I2C1
}
void I2C1_Write(uint8_t saddr, uint16_t reg, const uint8_t *data, uint16_t len)
{
volatile int tmp;
while (I2C1->SR2 & (1 << 1)); // Wait if busy
I2C1->CR1 |= (1 << 8); // START
while (!(I2C1->SR1 & (1 << 0))); // SB
I2C1->DR = saddr << 1; // Write address
while (!(I2C1->SR1 & (1 << 1))); // ADDR
tmp = I2C1->SR2;
// Send 16-bit register address
while (!(I2C1->SR1 & (1 << 7)));
I2C1->DR = (reg >> 8) & 0xFF;
while (!(I2C1->SR1 & (1 << 7)));
I2C1->DR = reg & 0xFF;
// Send data
for (uint16_t i = 0; i < len; i++)
{
while (!(I2C1->SR1 & (1 << 7)));
I2C1->DR = data[i];
}
while (!(I2C1->SR1 & (1 << 2))); // BTF
I2C1->CR1 |= (1 << 9); // STOP
}
void I2C1_Read(uint8_t saddr, uint16_t reg, uint8_t *data, uint16_t len)
{
volatile int tmp;
while (I2C1->SR2 & (1 << 1)); // Busy
I2C1->CR1 |= (1 << 8); // START
while (!(I2C1->SR1 & (1 << 0)));
I2C1->DR = saddr << 1; // Write mode
while (!(I2C1->SR1 & (1 << 1)));
tmp = I2C1->SR2;
while (!(I2C1->SR1 & (1 << 7)));
I2C1->DR = (reg >> 8) & 0xFF;
while (!(I2C1->SR1 & (1 << 7)));
I2C1->DR = reg & 0xFF;
while (!(I2C1->SR1 & (1 << 7)));
I2C1->CR1 |= (1 << 8); // Re-START
while (!(I2C1->SR1 & (1 << 0)));
I2C1->DR = (saddr << 1) | 1; // Read mode
while (!(I2C1->SR1 & (1 << 1)));
tmp = I2C1->SR2;
if (len == 1)
{
I2C1->CR1 &= ~(1 << 10); // ACK = 0
I2C1->CR1 |= (1 << 9); // STOP
while (!(I2C1->SR1 & (1 << 6)));
data[0] = I2C1->DR;
}
else
{
I2C1->CR1 |= (1 << 10); // ACK
for (uint16_t i = 0; i < len; i++)
{
if (i == len - 2)
I2C1->CR1 &= ~(1 << 10); // NACK before last byte
if (i == len - 1)
I2C1->CR1 |= (1 << 9); // STOP
while (!(I2C1->SR1 & (1 << 6)));
data[i] = I2C1->DR;
}
}
}
#ifndef ADAU1450_H_
#define ADAU1450_H_
#include <stdint.h>
#define ADAU1450_I2C_ADDR 0x38 // Make sure ADDR0 and ADDR1 = 0
#define PLL_CTRL0 0xF000
#define PLL_CTRL1 0xF001
#define PLL_CLK_SRC 0xF002
#define PLL_ENABLE 0xF003
#define PLL_LOCK 0xF004
#define MCLK_OUT_ENABLE 0xF005
#define SOFT_RESET 0xF890
#define HIBERNATE 0xF400
#define KILL_CORE 0xF403
#define START_CORE 0xF402
#define SYS_PWR 0xF050
#define SYS_DISABLE 0xF051
void adau1450_init(void);
void adau1450_write(uint16_t reg, uint8_t val);
uint8_t adau1450_read(uint16_t reg);
uint8_t adau1450_check_pll_lock(void);
#include "i2c.h"
#include "adau1450.h"
int main(void)
{
I2C1_Init();
adau1450_init();
uint8_t pll_val;
while (1)
{
pll_val = adau1450_read(PLL_CTRL0);
for (volatile int i = 0; i < 100000; i++);
}
}
And finnally, here is the screenshot of what I am getting on logic analyzer...



