K1Guitar/device/AD85020B/Drv_AD85020B.c

318 lines
9.9 KiB
C
Raw Permalink Normal View History

/*
* @Author: CTW
* @Date: 2025-11-07 14:37:55
* @FilePath: \PhoenixSMGT_Testproject\Drivers\AD85050\Drv_AD85020B.c
* @note: STM32 HAL AT32F403A
* I2C1 i2c_application GPIO I2C
* AD85020B_I2C_USE_HW 1=0=
* - HAL_I2C_Mem_Write -> i2c_memory_write /
* - HAL_Delay -> wk_delay_ms
* - HAL_StatusTypeDef -> AD85020B_StatusTypeDef
*/
#include "Drv_AD85020B.h"
#include "wk_system.h"
#include <stdio.h>
/* =====================================================================
* I2C1 AD85020B_I2C_USE_HW = 1
* i2c_application middlewares/i2c_application_library
* ===================================================================== */
#if AD85020B_I2C_USE_HW
#include "i2c_application.h"
#include "includes.h"
static void AD85020B_I2C_InitImpl(void)
{
wk_i2c1_init();
// gpio_init_type g;
//
// /* 使能 GPIOB / I2C1 时钟 */
// crm_periph_clock_enable(CRM_GPIOB_PERIPH_CLOCK, TRUE);
// crm_periph_clock_enable(CRM_I2C1_PERIPH_CLOCK, TRUE);
//
// /* PB6=SCL, PB7=SDA复用开漏 + 上拉 */
// gpio_default_para_init(&g);
// g.gpio_mode = GPIO_MODE_MUX;
// g.gpio_out_type = GPIO_OUTPUT_OPEN_DRAIN;
// g.gpio_pull = GPIO_PULL_UP;
// g.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE;
// g.gpio_pins = AD85020B_SCL_PIN;
// gpio_init(AD85020B_I2C_PORT, &g);
// g.gpio_pins = AD85020B_SDA_PIN;
// gpio_init(AD85020B_I2C_PORT, &g);
//
// /* I2C1 主机 100kHz */
// i2c_init(I2C1, I2C_FSMODE_DUTY_2_1, 100000);
// i2c_own_address1_set(I2C1, I2C_ADDRESS_MODE_7BIT, 0x0);
// i2c_ack_enable(I2C1, TRUE);
// i2c_clock_stretch_enable(I2C1, TRUE);
// i2c_general_call_enable(I2C1, FALSE);
// i2c_enable(I2C1, TRUE);
}
static AD85020B_StatusTypeDef AD85020B_I2C_WriteImpl(uint8_t reg, uint8_t data)
{
i2c_handle_type hi2c;
i2c_status_type status;
uint8_t buf = data;
hi2c.i2cx = I2C1;
/* i2c_memory_write: START → 器件地址+W → 寄存器(8bit) → 数据 → STOP
8 0x60 &0xFE */
status = i2c_memory_write(&hi2c,
I2C_MEM_ADDR_WIDIH_8,
AD85020B_I2C_ADDR_W,
reg, &buf, 1,
AD85020B_I2C_TIMEOUT);
if (status != I2C_OK)
{
printf("[AD85020B] HW_Write fail ret=0x%X inner=0x%X\r\n",
(unsigned)status, (unsigned)hi2c.error_code);
return AD85020B_ERROR;
}
return AD85020B_OK;
}
static AD85020B_StatusTypeDef AD85020B_I2C_ReadImpl(uint8_t reg, uint8_t *data)
{
i2c_handle_type hi2c;
i2c_status_type status;
if (data == 0) return AD85020B_ERROR;
hi2c.i2cx = I2C1;
/* i2c_memory_read: START → 地址+W → 寄存器 → RESTART → 地址+R → 数据 → STOP
8 0x60 |0x01 0x61 */
status = i2c_memory_read(&hi2c,
I2C_MEM_ADDR_WIDIH_8,
AD85020B_I2C_ADDR_W,
reg, data, 1,
AD85020B_I2C_TIMEOUT);
if (status != I2C_OK)
{
printf("[AD85020B] HW_Read fail ret=0x%X inner=0x%X\r\n",
(unsigned)status, (unsigned)hi2c.error_code);
return AD85020B_ERROR;
}
return AD85020B_OK;
}
/* =====================================================================
* I2C AD85020B_I2C_USE_HW = 0
* I2C GPIO
* ===================================================================== */
#else
#define I2C_DELAY() { volatile uint32_t i = 8; while (i--); }
static void SCL_High(void) { gpio_bits_set(AD85020B_I2C_PORT, AD85020B_SCL_PIN); }
static void SCL_Low(void) { gpio_bits_reset(AD85020B_I2C_PORT, AD85020B_SCL_PIN); }
static void SDA_High(void) { gpio_bits_set(AD85020B_I2C_PORT, AD85020B_SDA_PIN); }
static void SDA_Low(void) { gpio_bits_reset(AD85020B_I2C_PORT, AD85020B_SDA_PIN); }
static uint8_t SDA_Read(void)
{
return (gpio_input_data_bit_read(AD85020B_I2C_PORT, AD85020B_SDA_PIN) == SET) ? 1 : 0;
}
static void I2C_Start(void)
{
SDA_High(); SCL_High(); I2C_DELAY();
SDA_Low(); I2C_DELAY();
SCL_Low(); I2C_DELAY();
}
static void I2C_Stop(void)
{
SDA_Low(); SCL_High(); I2C_DELAY();
SDA_High(); I2C_DELAY();
}
static uint8_t I2C_SendByte(uint8_t data)
{
uint8_t i, ack;
for (i = 0; i < 8; i++)
{
if (data & 0x80) SDA_High(); else SDA_Low();
data <<= 1;
I2C_DELAY();
SCL_High(); I2C_DELAY();
SCL_Low(); I2C_DELAY();
}
SDA_High(); I2C_DELAY();
SCL_High(); I2C_DELAY();
ack = SDA_Read();
SCL_Low(); I2C_DELAY();
return ack;
}
static uint8_t I2C_RecvByte(uint8_t ack)
{
uint8_t i, data = 0;
SDA_High();
for (i = 0; i < 8; i++)
{
SCL_High(); I2C_DELAY();
data = (data << 1) | SDA_Read();
SCL_Low(); I2C_DELAY();
}
if (ack) SDA_High(); else SDA_Low();
I2C_DELAY();
SCL_High(); I2C_DELAY();
SCL_Low(); I2C_DELAY();
SDA_High(); I2C_DELAY();
return data;
}
static void AD85020B_I2C_InitImpl(void)
{
gpio_init_type g;
gpio_default_para_init(&g);
g.gpio_mode = GPIO_MODE_OUTPUT;
g.gpio_out_type = GPIO_OUTPUT_OPEN_DRAIN;
g.gpio_pull = GPIO_PULL_UP;
g.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE;
g.gpio_pins = AD85020B_SCL_PIN;
gpio_init(AD85020B_I2C_PORT, &g);
g.gpio_pins = AD85020B_SDA_PIN;
gpio_init(AD85020B_I2C_PORT, &g);
SDA_High();
SCL_High();
}
static AD85020B_StatusTypeDef AD85020B_I2C_WriteImpl(uint8_t reg, uint8_t data)
{
I2C_Start();
if (I2C_SendByte(AD85020B_I2C_ADDR_W)) { printf("[AD85020B] SW ADDR_NACK\r\n"); return AD85020B_ERROR; }
if (I2C_SendByte(reg)) { printf("[AD85020B] SW REG_NACK reg=0x%02X\r\n", reg); return AD85020B_ERROR; }
if (I2C_SendByte(data)) { printf("[AD85020B] SW DATA_NACK\r\n"); return AD85020B_ERROR; }
I2C_Stop();
return AD85020B_OK;
}
static AD85020B_StatusTypeDef AD85020B_I2C_ReadImpl(uint8_t reg, uint8_t *data)
{
if (data == 0) return AD85020B_ERROR;
I2C_Start();
if (I2C_SendByte(AD85020B_I2C_ADDR_W)) return AD85020B_ERROR;
if (I2C_SendByte(reg)) return AD85020B_ERROR;
I2C_Start();
if (I2C_SendByte(AD85020B_I2C_ADDR_R)) return AD85020B_ERROR;
*data = I2C_RecvByte(1);
I2C_Stop();
return AD85020B_OK;
}
#endif /* AD85020B_I2C_USE_HW */
/* =====================================================================
* /
* ===================================================================== */
void AD85020B_I2C_Init(void)
{
AD85020B_I2C_InitImpl();
}
AD85020B_StatusTypeDef AD85020B_I2C_Write(uint8_t reg, uint8_t data)
{
return AD85020B_I2C_WriteImpl(reg, data);
}
AD85020B_StatusTypeDef AD85020B_I2C_Read(uint8_t reg, uint8_t *data)
{
return AD85020B_I2C_ReadImpl(reg, data);
}
/**
* @brief AD85020B
* @retval AD85020B_StatusTypeDef:
*/
AD85020B_StatusTypeDef AD85020B_Init(void)
{
AD85020B_StatusTypeDef status;
uint8_t vol = 0x2c;
AD85020B_I2C_Init();
wk_delay_ms(1); // 文档要求 AMP_SDB 拉高后延时≥20ms
/* 步骤2软件复位文档SCTL6寄存器BIT5=0 */
status = AD85020B_I2C_Write(AD85020B_REG_SCTL6, AD85020B_SW_RESET);
if (status != AD85020B_OK) return status;
wk_delay_ms(20); // 等待复位完成文档未明确建议10~50ms
/* 步骤3复位后恢复正常模式BIT5=1 */
status = AD85020B_I2C_Write(AD85020B_REG_SCTL6, AD85020B_SW_NORMAL);
if (status != AD85020B_OK) return status;
wk_delay_ms(10);
/* 步骤4配置输入格式文档SCTL1默认I2S格式0x00 */
status = AD85020B_I2C_Write(AD85020B_REG_SCTL1, 0x00);
if (status != AD85020B_OK) return status;
wk_delay_ms(10);
// /* 步骤5配置采样率文档SCTL2默认0x9144.1/48kHz64x BCLK */
// status = AD85020B_I2C_Write(AD85020B_REG_SCTL2, 0x91);
// if (status != AD85020B_OK) return status;
// wk_delay_ms(10);
/* 步骤7设置主音量文档MVOL0x18对应0dB避免过载 */
status = AD85020B_I2C_Write(AD85020B_REG_MVOL, vol);
if (status != AD85020B_OK) return status;
wk_delay_ms(10);
status = AD85020B_I2C_Write(AD85020B_REG_MVOL, vol);
if (status != AD85020B_OK) return status;
wk_delay_ms(10);
status = AD85020B_I2C_Write(AD85020B_REG_MVOL, vol);
if (status != AD85020B_OK) return status;
wk_delay_ms(10);
status = AD85020B_I2C_Write(AD85020B_REG_HEADPHONEVOL, vol);
if (status != AD85020B_OK) return status;
wk_delay_ms(10);
/* 步骤8设置通道音量0x04~0x090x18对应0dB避免过载 */
status = AD85020B_I2C_Write(0x04, vol);
if (status != AD85020B_OK) return status;
wk_delay_ms(10);
status = AD85020B_I2C_Write(0x05, vol);
if (status != AD85020B_OK) return status;
wk_delay_ms(10);
status = AD85020B_I2C_Write(0x06, vol);
if (status != AD85020B_OK) return status;
wk_delay_ms(10);
status = AD85020B_I2C_Write(0x07, vol);
if (status != AD85020B_OK) return status;
wk_delay_ms(10);
status = AD85020B_I2C_Write(0x08, vol);
if (status != AD85020B_OK) return status;
wk_delay_ms(10);
status = AD85020B_I2C_Write(0x09, vol);
if (status != AD85020B_OK) return status;
wk_delay_ms(10);
/* 步骤6解除静音文档SCTL3MMUTE=00x00 */
status = AD85020B_I2C_Write(AD85020B_REG_SCTL3, 0x00);
if (status != AD85020B_OK) return status;
wk_delay_ms(10);
return AD85020B_OK;
}