CS43L12 DAC芯片驅(qū)動

@[toc](CS43L12 DAC芯片驅(qū)動)

音頻數(shù)據(jù)通過MIC采集上來后有的的PDM數(shù)據(jù)有的直接是PCM數(shù)據(jù),CS43L12做的就是將PCM數(shù)據(jù)播放出來。

CubeMX配置如下

音頻數(shù)據(jù)傳輸I2S接口


在這里插入圖片描述

開DMA雙緩沖


在這里插入圖片描述

芯片配置I2C通訊


在這里插入圖片描述

驅(qū)動代碼

/**
 *  @file CS43L12_Driver.c
 *
 *  @date 2021-03-10
 *
 *  @author aron566
 *
 *  @copyright Copyright (c) 2021 aron566 <aron566@163.com>.
 *
 *  @brief CS43L12 DAC芯片驅(qū)動接口
 *
 *  @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/**< 啟動打印調(diào)試*/
/*CS43L12設備I2C地址,7Bit地址模式[即:100101<AD0><R/W>],最后一位由AD0引腳控制*/
#define AD0_PIN_LOW_LEVEL       1   /**< 初始化為下拉低電平狀態(tài)*/  
#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數(shù)據(jù)直接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)
{
  /*讀取電源設置狀態(tài)*/
  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)
{
  /*讀取電源設置狀態(tài)*/
  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)
{
  /*讀取電源設置狀態(tài)*/
  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   設置設備參數(shù)
  * @param   [in]None
  * @return  None.
  * @author  aron566
  * @version V1.0
  * @date    2021-03-10
  ******************************************************************
  */
static inline void Set_Cfg(void)
{  
  /*讀取參數(shù)*/
  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);
  /*設置數(shù)據(jù)格式 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 驅(qū)動初始化
  * @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芯片驅(qū)動接口
 *  
 *  @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 驅(qū)動初始化*/
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 *********************************/

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容