CS43L12 DAC芯片驱动

@[toc](CS43L12 DAC芯片驱动)

音频数据通过MIC采集上来后有的的PDM数据有的直接是PCM数据,CS43L12做的就是将PCM数据播放出来。

CubeMX配置如下

音频数据传输I2S接口


在这里插入图片描述

开DMA双缓冲


在这里插入图片描述

芯片配置I2C通讯


在这里插入图片描述

驱动代码

/**
 *  @file CS43L12_Driver.c
 *
 *  @date 2021-03-10
 *
 *  @author aron566
 *
 *  @copyright Copyright (c) 2021 aron566 <aron566@163.com>.
 *
 *  @brief CS43L12 DAC芯片驱动接口
 *
 *  @details 1、CS43L12
 *
 *  @version V1.0
 */
#ifdef __cplusplus ///<use C compiler
extern "C" {
#endif
/** Includes -----------------------------------------------------------------*/
/* Private includes ----------------------------------------------------------*/
#include "CS43L12_Driver.h"
#include "main.h"
#include "SAI_Port.h"
/** Private typedef ----------------------------------------------------------*/
/** Private macros -----------------------------------------------------------*/
#define ENABLE_CS43L12_DEBUG    1/**< 启动打印调试*/
/*CS43L12设备I2C地址,7Bit地址模式[即:100101<AD0><R/W>],最后一位由AD0引脚控制*/
#define AD0_PIN_LOW_LEVEL       1   /**< 初始化为下拉低电平状态*/  
#if AD0_PIN_LOW_LEVEL
  #define DEV_ADDR              0x94
#else
  #define DEV_ADDR              0x96
#endif
/*CS43L12设备I2C写操作地址*/
#define DEV_ADDR_WRITE          (DEV_ADDR|0x00)
/*CS43L12设备I2C读操作地址*/
#define DEV_ADDR_READ           (DEV_ADDR|0x01)

/*CS43L12寄存器地址*/
#define REG_CHIP_ID             0x01
#define REG_POWER_CTL           0x02
#define REG_SPEED_CTL           0x03
#define REG_INTERFACE_CFG       0x04
#define REG_DAC_OUT_CTL         0x08
#define REG_DAC_CTL             0x09/**< default:bit7:0 bit6:0 PCM数据直接DAC输出 01b则通过处理引擎*/

/*The DATA_SEL[1:0] bit in Reg09h must be set to 01b to enable function control in this register.*/
#define REG_PCMA_MIXER_CTL      0x10
#define REG_PCMB_MIXER_CTL      0x11

#define REG_BEEP_FQ_TIMG_CFG    0x12
#define REG_BEEP_OFF_TIME_VOL   0x13

#define REG_BEEP_CFG_TONE_CFG   0x14

#define REG_TONE_CTL            0x15
        
#define REG_A_OUT_VOL_CTL       0x16/**< 输出音量控制*/
#define REG_B_OUT_VOL_CTL       0x17

#define REG_PCM_MIXER_CH_SEL    0x18

#define REG_LIMIT_THRESHOLD_SZC 0x19

#define REG_LIMIT_RELEASE_RATE  0x1A
#define REG_LIMIT_ATTACK_RATE   0x1B

#define REG_STATUS_READ_ONLY    0x20

#define REG_CHARGE_PUMP_FQ      0x21
        
/*16BIT位*/        
#define REG_BIT0                (1U<<0)
#define REG_BIT1                (1U<<1)
#define REG_BIT2                (1U<<2)
#define REG_BIT3                (1U<<3)
#define REG_BIT4                (1U<<4)
#define REG_BIT5                (1U<<5)
#define REG_BIT6                (1U<<6)
#define REG_BIT7                (1U<<7)
#define REG_BIT8                (1U<<8)
#define REG_BIT9                (1U<<9)
#define REG_BIT10               (1U<<10)
#define REG_BIT11               (1U<<11)
#define REG_BIT12               (1U<<12)
#define REG_BIT13               (1U<<13)
#define REG_BIT14               (1U<<14)
#define REG_BIT15               (1U<<15)
/** Private constants --------------------------------------------------------*/
/** Public variables ---------------------------------------------------------*/
extern I2C_HandleTypeDef hi2c1;
/** Private variables --------------------------------------------------------*/
static uint8_t Send_Val_Buf[2];
static uint8_t Reg_Val_Buf[2];
/** Private function prototypes ----------------------------------------------*/
#if ENABLE_CS43L12_DEBUG
static void Display_Chip_ID(void);
#endif
static void Set_Device_AD0(void);
static void Power_On_Off(CS43L12_DRIVER_CH_Typedef_t Ch, CS43L12_DRIVER_POWER_Typedef_t On_Off);
/** Private user code --------------------------------------------------------*/

/** Private application code -------------------------------------------------*/
/*******************************************************************************
*
*       Static code
*
********************************************************************************
*/
#if ENABLE_CS43L12_DEBUG
/**
  ******************************************************************
  * @brief   CS43L12 chip id打印
  * @param   [in]None.
  * @return  None.
  * @author  aron566
  * @version V1.0
  * @date    2021-03-10
  ******************************************************************
  */
static inline void Display_Chip_ID(void)
{
  Send_Val_Buf[0] = REG_CHIP_ID;
  HAL_I2C_Master_Transmit(&hi2c1, DEV_ADDR_WRITE, Send_Val_Buf, 1, 100);
  HAL_I2C_Master_Receive(&hi2c1, DEV_ADDR_READ, Reg_Val_Buf, 1, 100);
  printf("Chip ID REG:%02X, VAL:%02X.\r\n", Send_Val_Buf[0], Reg_Val_Buf[0]);/**< 0xD8 0xD9*/
}
#endif

/**
  ******************************************************************
  * @brief   CS43L12 上电初始化
  * @param   [in]None.
  * @return  None.
  * @author  aron566
  * @version V1.0
  * @date    2021-03-11
  ******************************************************************
  */
static inline void Device_PowerOn_Init(void)
{
  /*HOLD RESET PIN LOW LEVEL 10ms*/
  HAL_GPIO_WritePin(DAC_RST_GPIO_Port, DAC_RST_Pin, GPIO_PIN_RESET);
  HAL_Delay(10);
  HAL_GPIO_WritePin(DAC_RST_GPIO_Port, DAC_RST_Pin, GPIO_PIN_SET);
}

/**
  ******************************************************************
  * @brief   CS43L12 进入配置模式
  * @param   [in]None.
  * @return  None.
  * @author  aron566
  * @version V1.0
  * @date    2021-03-11
  ******************************************************************
  */
static inline void Entry_Config_Mode(void)
{
  /*读取电源设置状态*/
  Send_Val_Buf[0] = REG_POWER_CTL;
  HAL_I2C_Master_Transmit(&hi2c1, DEV_ADDR_WRITE, Send_Val_Buf, 1, 100);
  HAL_I2C_Master_Receive(&hi2c1, DEV_ADDR_READ, Reg_Val_Buf, 1, 100);
  
  /*开启PDN Bit解锁设置*/
  Send_Val_Buf[1] = Reg_Val_Buf[0] | (REG_BIT0);
  HAL_I2C_Master_Transmit(&hi2c1, DEV_ADDR_WRITE, Send_Val_Buf, 2, 100);
  
#if ENABLE_CS43L12_DEBUG
  HAL_I2C_Master_Transmit(&hi2c1, DEV_ADDR_WRITE, Send_Val_Buf, 1, 100);
  HAL_I2C_Master_Receive(&hi2c1, DEV_ADDR_READ, Reg_Val_Buf, 1, 100);
  printf("Entry DAC Power REG:%02X, VAL:%02X.\r\n", Send_Val_Buf[0], Reg_Val_Buf[0]);
#endif
}

/**
  ******************************************************************
  * @brief   CS43L12 推出配置模式
  * @param   [in]None.
  * @return  None.
  * @author  aron566
  * @version V1.0
  * @date    2021-03-11
  ******************************************************************
  */
static inline void Exit_Config_Mode(void)
{
  /*读取电源设置状态*/
  Send_Val_Buf[0] = REG_POWER_CTL;
  HAL_I2C_Master_Transmit(&hi2c1, DEV_ADDR_WRITE, Send_Val_Buf, 1, 100);
  HAL_I2C_Master_Receive(&hi2c1, DEV_ADDR_READ, Reg_Val_Buf, 1, 100);
  
  /*关闭PDN Bit上锁*/
  Send_Val_Buf[1] = Send_Val_Buf[1] & (~REG_BIT0);
  HAL_I2C_Master_Transmit(&hi2c1, DEV_ADDR_WRITE, Send_Val_Buf, 2, 100);

#if ENABLE_CS43L12_DEBUG
  HAL_I2C_Master_Transmit(&hi2c1, DEV_ADDR_WRITE, Send_Val_Buf, 1, 100);
  HAL_I2C_Master_Receive(&hi2c1, DEV_ADDR_READ, Reg_Val_Buf, 1, 100);
  printf("Exit DAC Power REG:%02X, VAL:%02X.\r\n", Send_Val_Buf[0], Reg_Val_Buf[0]);
#endif
}

/**
  ******************************************************************
  * @brief   设置设备地址
  * @param   [in]None
  * @return  None.
  * @author  aron566
  * @version V1.0
  * @date    2021-03-10
  ******************************************************************
  */
static inline void Set_Device_AD0(void)
{
#if AD0_PIN_LOW_LEVEL
  HAL_GPIO_WritePin(DAC_ADDR_GPIO_Port, DAC_ADDR_Pin, GPIO_PIN_RESET);
#else
  HAL_GPIO_WritePin(DAC_ADDR_GPIO_Port, DAC_ADDR_Pin, GPIO_PIN_SET);
#endif
}

/**
  ******************************************************************
  * @brief   启停设备DACx电源
  * @param   [in]Ch 声道编号
  * @param   [in]On_Off 启动或关闭
  * @return  None.
  * @author  aron566
  * @version V1.0
  * @date    2021-03-10
  ******************************************************************
  */
static void Power_On_Off(CS43L12_DRIVER_CH_Typedef_t Ch, CS43L12_DRIVER_POWER_Typedef_t On_Off)
{
  /*读取电源设置状态*/
  Send_Val_Buf[0] = REG_POWER_CTL;
  HAL_I2C_Master_Transmit(&hi2c1, DEV_ADDR_WRITE, Send_Val_Buf, 1, 100);
  HAL_I2C_Master_Receive(&hi2c1, DEV_ADDR_READ, Reg_Val_Buf, 1, 100);
  Send_Val_Buf[1] = Reg_Val_Buf[0];
  
  /*关闭*/
  if(On_Off == CS43L12_DRIVER_POWER_OFF)
  {
    /*左*/
    if(Ch == CS43L12_DRIVER_LEFT_CH)
    {
      Send_Val_Buf[1] = Send_Val_Buf[1] | (REG_BIT5);
    }
    /*右*/
    if(Ch == CS43L12_DRIVER_RIGHT_CH)
    {
      Send_Val_Buf[1] = Send_Val_Buf[1] | (REG_BIT6);
    }
  }
  /*打开*/
  else
  {
    /*左*/
    if(Ch == CS43L12_DRIVER_LEFT_CH)
    {
      Send_Val_Buf[1] = Send_Val_Buf[1] & (~REG_BIT5);
    }
    /*右*/
    if(Ch == CS43L12_DRIVER_RIGHT_CH)
    {
      Send_Val_Buf[1] = Send_Val_Buf[1] & (~REG_BIT6);
    }
  }
  
  HAL_I2C_Master_Transmit(&hi2c1, DEV_ADDR_WRITE, Send_Val_Buf, 2, 100);
  
#if ENABLE_CS43L12_DEBUG
  HAL_I2C_Master_Transmit(&hi2c1, DEV_ADDR_WRITE, Send_Val_Buf, 1, 100);
  HAL_I2C_Master_Receive(&hi2c1, DEV_ADDR_READ, Reg_Val_Buf, 1, 100);
  printf("DAC Power REG:%02X, VAL:%02X.\r\n", Send_Val_Buf[0], Reg_Val_Buf[0]);
#endif
}

/**
  ******************************************************************
  * @brief   设置设备参数
  * @param   [in]None
  * @return  None.
  * @author  aron566
  * @version V1.0
  * @date    2021-03-10
  ******************************************************************
  */
static inline void Set_Cfg(void)
{  
  /*读取参数*/
  Send_Val_Buf[0] = REG_INTERFACE_CFG;
  HAL_I2C_Master_Transmit(&hi2c1, DEV_ADDR_WRITE, Send_Val_Buf, 1, 100);
  HAL_I2C_Master_Receive(&hi2c1, DEV_ADDR_READ, Reg_Val_Buf, 1, 100);
#if ENABLE_CS43L12_DEBUG
  printf("Interface CFG REG:%02X, VAL:%02X.\r\n", Send_Val_Buf[0], Reg_Val_Buf[0]);
#endif
  
  /*设置为Slave*/
  Send_Val_Buf[1] = Reg_Val_Buf[0] & (~REG_BIT6);
  /*设置数据格式 101*/
  Send_Val_Buf[1] = Send_Val_Buf[1] | REG_BIT5;
  Send_Val_Buf[1] = Send_Val_Buf[1] & (~REG_BIT4);
  Send_Val_Buf[1] = Send_Val_Buf[1] | REG_BIT3;
#if ENABLE_CS43L12_DEBUG
  printf("Set Interface CFG REG:%02X, VAL:%02X.\r\n", Send_Val_Buf[0], Send_Val_Buf[1]);
#endif
  HAL_I2C_Master_Transmit(&hi2c1, DEV_ADDR_WRITE, Send_Val_Buf, 2, 100);
  
#if ENABLE_CS43L12_DEBUG
  HAL_I2C_Master_Transmit(&hi2c1, DEV_ADDR_WRITE, Send_Val_Buf, 1, 100);
  HAL_I2C_Master_Receive(&hi2c1, DEV_ADDR_READ, Reg_Val_Buf, 1, 100);
  printf("After Interface CFG REG:%02X, VAL:%02X.\r\n", Send_Val_Buf[0], Reg_Val_Buf[0]);
#endif
}

/** Public application code --------------------------------------------------*/
/*******************************************************************************
*
*       Public code
*
********************************************************************************
*/
/**
  ******************************************************************
  * @brief   CS43L12 启动DAC
  * @param   [in]None
  * @return  None.
  * @author  aron566
  * @version V1.0
  * @date    2021-03-11
  ******************************************************************
  */
void CS43L12_Driver_DAC_Out(int16_t *Audio_Data, uint32_t len)
{

}

/**
  ******************************************************************
  * @brief   CS43L12 驱动初始化
  * @param   [in]None
  * @return  None.
  * @author  aron566
  * @version V1.0
  * @date    2021-03-10
  ******************************************************************
  */
void CS43L12_Driver_Init(void)
{
  /*设备上电初始化*/
  Device_PowerOn_Init();
  
  /*设置设备地址*/
  Set_Device_AD0();
  
  /*打印设备ID*/
#if ENABLE_CS43L12_DEBUG
  Display_Chip_ID();
#endif
  
  /*进入配置模式*/
  Entry_Config_Mode();

  /*配置设备为Slave 右对齐16bit*/
  Set_Cfg();
  
  /*设置通道电源*/
  Power_On_Off(CS43L12_DRIVER_LEFT_CH, CS43L12_DRIVER_POWER_ON);
  Power_On_Off(CS43L12_DRIVER_RIGHT_CH, CS43L12_DRIVER_POWER_ON);
  
  /*退出配置模式*/
  Exit_Config_Mode();
}

#ifdef __cplusplus ///<end extern c
}
#endif
/******************************** End of file *********************************/

/**
 *  @file CS43L12_Driver.h
 *
 *  @date 2021-03-10
 *
 *  @author Copyright (c) 2021 aron566 <aron566@163.com>.
 *
 *  @brief CS43L12 DAC芯片驱动接口
 *  
 *  @version V1.0
 */
#ifndef CS43L12_DRIVER_H
#define CS43L12_DRIVER_H
#ifdef __cplusplus ///<use C compiler
extern "C" {
#endif
/** Includes -----------------------------------------------------------------*/
#include <stdint.h> /**< need definition of uint8_t */
#include <stddef.h> /**< need definition of NULL    */
#include <stdbool.h>/**< need definition of BOOL    */
#include <stdio.h>  /**< if need printf             */
#include <stdlib.h>
#include <string.h>
#include <limits.h> /**< need variable max value    */
/** Private includes ---------------------------------------------------------*/

/** Private defines ----------------------------------------------------------*/

/** Exported typedefines -----------------------------------------------------*/
/*CS43L12声道编号*/
typedef enum
{
  CS43L12_DRIVER_LEFT_CH = 0,
  CS43L12_DRIVER_RIGHT_CH
}CS43L12_DRIVER_CH_Typedef_t;

/*CS43L12声道输出开关*/
typedef enum
{
  CS43L12_DRIVER_POWER_OFF = 0,
  CS43L12_DRIVER_POWER_ON
}CS43L12_DRIVER_POWER_Typedef_t;

/** Exported constants -------------------------------------------------------*/

/** Exported macros-----------------------------------------------------------*/
/** Exported variables -------------------------------------------------------*/
/** Exported functions prototypes --------------------------------------------*/

/*CS43L12 驱动初始化*/
void CS43L12_Driver_Init(void);
/*CS43L12 启动DAC*/
void CS43L12_Driver_DAC_Out(int16_t *Audio_Data, uint32_t len);

#ifdef __cplusplus ///<end extern c
}
#endif
#endif
/******************************** End of file *********************************/

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容