{"id":2612,"date":"2024-06-21T04:36:56","date_gmt":"2024-06-21T04:36:56","guid":{"rendered":"https:\/\/blog.embeddedexpert.io\/?p=2612"},"modified":"2024-06-21T04:36:58","modified_gmt":"2024-06-21T04:36:58","slug":"working-with-stm32-and-i2s-part-4-cs43l22-initialization-and-sound-generation","status":"publish","type":"post","link":"https:\/\/blog.embeddedexpert.io\/?p=2612","title":{"rendered":"Working with STM32 and I2S Part 4: CS43L22 Initialization and sound generation"},"content":{"rendered":"\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"200\" height=\"150\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/06\/Inter-IC-Sound-1-1.jpg\" alt=\"\" class=\"wp-image-2613\" \/><\/figure><\/div>\n\n\n\n<p>In the previous guide (<a rel=\"noreferrer noopener\" href=\"https:\/\/blog.embeddedexpert.io\/?p=2588\" data-type=\"URL\" data-id=\"https:\/\/blog.embeddedexpert.io\/?p=2588\" target=\"_blank\">here<\/a>), we were able to transmit data over I2S using DMA, in this guide, we shall initialize the CS43L22 which is stereo DAC.<\/p>\n\n\n\n<p>In this guide, we shall cover the following:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Enabling circular mode for DMA.<\/li><li>Header file development.<\/li><li>Source file development.<\/li><li>Main code.<\/li><li>Source code download.<\/li><li>Results.<\/li><\/ul>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">18. Enabling Circular Mode for DMA:<\/h2>\n\n\n\n<p>In I2S source file, the <strong><em><strong>I2S3_Init<\/strong><\/em><\/strong> function:<\/p>\n\n\n\n<p>In the DMA configuration add the following to the configuration:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"378\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/06\/2024-06-21_06-59-12-1024x378.jpg\" alt=\"\" class=\"wp-image-2614\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/06\/2024-06-21_06-59-12-1024x378.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/06\/2024-06-21_06-59-12-300x111.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/06\/2024-06-21_06-59-12-768x283.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/06\/2024-06-21_06-59-12-1536x567.jpg 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/06\/2024-06-21_06-59-12-2048x756.jpg 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/06\/2024-06-21_06-59-12-1150x424.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/06\/2024-06-21_06-59-12-750x277.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/06\/2024-06-21_06-59-12-400x148.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/06\/2024-06-21_06-59-12-250x92.jpg 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">DMA_SxCR_CIRC<\/pre><\/div>\n\n\n\n<p>Hence the configuration as following:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">\t\/*Configure DMA with the following parameters\n\t * 1.Channel is 0.\n\t * Memory increment mode.\n\t * Direction Memory to Peripheral.\n\t * Enable Transfer Complete Interrupt.\n\t * Enable Circular Mode\n\t *\n\t * *\/\n\tDMA1_Stream7-&gt;CR|=(0x00&lt;&lt;DMA_SxCR_CHSEL_Pos)|DMA_SxCR_MINC|DMA_SxCR_DIR_0|DMA_SxCR_TCIE|DMA_SxCR_CIRC;<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>That all for the DMA section.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">19. Header File Development:<\/h2>\n\n\n\n<p>Create new header file with name of <strong><em>CS43L22<\/em><\/strong>.h <\/p>\n\n\n\n<p>Within the header file:<\/p>\n\n\n\n<p>Include the header guard as following:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#ifndef CS43L22_H_\n#define CS43L22_H_\n\n\n#endif \/* CS43L22_H_ *\/<\/pre><\/div>\n\n\n\n<p>Within the header file:<\/p>\n\n\n\n<p>Include stdint library as following:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#include &quot;stdint.h&quot;<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>Declare the following define statements for the CS43L22 registers:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#define POWER_CONTROL1\t\t\t\t0x02\n#define POWER_CONTROL2\t\t\t\t0x04\n#define CLOCKING_CONTROL \t  \t\t0x05\n#define INTERFACE_CONTROL1\t\t\t0x06\n#define INTERFACE_CONTROL2\t\t\t0x07\n#define PASSTHROUGH_A\t\t\t\t0x08\n#define PASSTHROUGH_B\t\t\t\t0x09\n#define MISCELLANEOUS_CONTRLS\t\t0x0E\n#define PLAYBACK_CONTROL\t\t\t0x0F\n#define PASSTHROUGH_VOLUME_A\t\t0x14\n#define PASSTHROUGH_VOLUME_B\t\t0x15\n#define PCM_VOLUME_A\t\t\t\t0x1A\n#define PCM_VOLUME_B\t\t\t\t0x1B\n#define CONFIG_00\t\t\t\t\t0x00\n#define CONFIG_47\t\t\t\t\t0x47\n#define CONFIG_32\t\t\t\t\t0x32<\/pre><\/div>\n\n\n\n<p>Registers of the volume control:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#define CS43L22_REG_MASTER_A_VOL    0x20\n#define CS43L22_REG_MASTER_B_VOL    0x21<\/pre><\/div>\n\n\n\n<p>Device address:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#define DAC_I2C_ADDR \t\t\t\t(0x94&gt;&gt;1)<\/pre><\/div>\n\n\n\n<p>Note: The address shifted to right by 1 since the i2c driver will shift the address to left 1.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Macro for mute:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#define CS43_MUTE\t\t\t\t \t0x00<\/pre><\/div>\n\n\n\n<p>Channel selection:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#define CS43_RIGHT\t\t\t\t\t0x01\n#define CS43_LEFT\t\t\t\t \t0x02\n#define CS43_RIGHT_LEFT\t \t\t\t0x03<\/pre><\/div>\n\n\n\n<p>Convert volume:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#define VOLUME_CONVERT_A(Volume)    (((Volume) &gt; 100)? 255:((uint8_t)(((Volume) * 255) \/ 100)))\n#define VOLUME_CONVERT_D(Volume)    (((Volume) &gt; 100)? 24:((uint8_t)((((Volume) * 48) \/ 100) - 24)))<\/pre><\/div>\n\n\n\n<p>Type of inputs either I2S or analog:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">typedef enum\n{\n\tMODE_I2S = 0,\n\tMODE_ANALOG,\n}CS43_MODE;<\/pre><\/div>\n\n\n\n<p>Declare the following functions:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">void CS43_Init(CS43_MODE outputMode);\nvoid CS43_Enable_RightLeft(uint8_t side);\nvoid CS43_SetVolume(uint8_t volume);\nvoid CS43_Start(void);\nvoid CS43_Stop(void);\nvoid CS43L22_Pin_RST_Init(void);\nvoid CS43L22_RST_Pin_Low(void);\nvoid CS43L22_RST_Pin_High(void);\n<\/pre><\/div>\n\n\n\n<p>Hence the entire header file as following:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#ifndef CS43L22_H_\n#define CS43L22_H_\n\n#include &quot;stdint.h&quot;\n\n#define POWER_CONTROL1\t\t\t\t0x02\n#define POWER_CONTROL2\t\t\t\t0x04\n#define CLOCKING_CONTROL \t  \t\t0x05\n#define INTERFACE_CONTROL1\t\t\t0x06\n#define INTERFACE_CONTROL2\t\t\t0x07\n#define PASSTHROUGH_A\t\t\t\t0x08\n#define PASSTHROUGH_B\t\t\t\t0x09\n#define MISCELLANEOUS_CONTRLS\t\t0x0E\n#define PLAYBACK_CONTROL\t\t\t0x0F\n#define PASSTHROUGH_VOLUME_A\t\t0x14\n#define PASSTHROUGH_VOLUME_B\t\t0x15\n#define PCM_VOLUME_A\t\t\t\t0x1A\n#define PCM_VOLUME_B\t\t\t\t0x1B\n#define CONFIG_00\t\t\t\t\t0x00\n#define CONFIG_47\t\t\t\t\t0x47\n#define CONFIG_32\t\t\t\t\t0x32\n\n#define CS43L22_REG_MASTER_A_VOL    0x20\n#define CS43L22_REG_MASTER_B_VOL    0x21\n\n#define DAC_I2C_ADDR \t\t\t\t(0x94&gt;&gt;1)\n\n#define CS43_MUTE\t\t\t\t \t0x00\n\n#define CS43_RIGHT\t\t\t\t\t0x01\n#define CS43_LEFT\t\t\t\t \t0x02\n#define CS43_RIGHT_LEFT\t \t\t\t0x03\n\n#define VOLUME_CONVERT_A(Volume)    (((Volume) &gt; 100)? 255:((uint8_t)(((Volume) * 255) \/ 100)))\n#define VOLUME_CONVERT_D(Volume)    (((Volume) &gt; 100)? 24:((uint8_t)((((Volume) * 48) \/ 100) - 24)))\n\n\ntypedef enum\n{\n\tMODE_I2S = 0,\n\tMODE_ANALOG,\n}CS43_MODE;\n\n\n\n\n\/\/------------ Public functions ------------\/\/\nvoid CS43_Init(CS43_MODE outputMode);\nvoid CS43_Enable_RightLeft(uint8_t side);\nvoid CS43_SetVolume(uint8_t volume);\nvoid CS43_Start(void);\nvoid CS43_Stop(void);\nvoid CS43L22_Pin_RST_Init(void);\nvoid CS43L22_RST_Pin_Low(void);\nvoid CS43L22_RST_Pin_High(void);\n\n#endif \/* CS43L22_H_ *\/<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">20. Source File Development:<\/h2>\n\n\n\n<p>Create new source file with name of <strong><em>CS43L22<\/em><\/strong>.c.<\/p>\n\n\n\n<p>Within the source file:<\/p>\n\n\n\n<p>Include the i2c and and <strong><em>CS43L22<\/em><\/strong> header files:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#include &quot;i2c.h&quot;\n#include &quot;CS43L22.h&quot;<\/pre><\/div>\n\n\n\n<p>Declare an array that hold some variables:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">static uint8_t iData[2];<\/pre><\/div>\n\n\n\n<p>Since we need to read\/write from\/to chip, we need to declare the following two functions:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">\/\/ Function(1): Write to register\nstatic void write_register(uint8_t reg, uint8_t *data)\n{\n\tiData[0] = reg;\n\tiData[1] = data[0];\n\ti2c_writeByte(DAC_I2C_ADDR, (char)iData[0], (char)iData[1]);\n\n}\n\/\/ Function(2): Read from register\nstatic void read_register(uint8_t reg, uint8_t *data)\n{\n\tchar tempData=0;\n\ti2c_readByte(DAC_I2C_ADDR,(char)reg, &amp;tempData);\n\t*data=tempData;\n}\n<\/pre><\/div>\n\n\n\n<p>First one is to write to certain register and the second one is for reading from a register.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Since the chip features hardware reset which is connected to PD4 as shown in the schematic:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"578\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/06\/2024-06-21_07-19-41-1024x578.jpg\" alt=\"\" class=\"wp-image-2616\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/06\/2024-06-21_07-19-41-1024x578.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/06\/2024-06-21_07-19-41-300x169.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/06\/2024-06-21_07-19-41-768x434.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/06\/2024-06-21_07-19-41-1536x867.jpg 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/06\/2024-06-21_07-19-41-2048x1156.jpg 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/06\/2024-06-21_07-19-41-1150x649.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/06\/2024-06-21_07-19-41-750x422.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/06\/2024-06-21_07-19-41-400x225.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/06\/2024-06-21_07-19-41-250x141.jpg 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>For the pin initialization:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">void CS43L22_Pin_RST_Init(void)\n{\n\tRCC-&gt;AHB1ENR|=RCC_AHB1ENR_GPIODEN;\n\n\tGPIOD-&gt;MODER|=GPIO_MODER_MODE4_0;\n\tGPIOD-&gt;MODER&amp;=~GPIO_MODER_MODE4_1;\n}<\/pre><\/div>\n\n\n\n<p>For setting the pin either high or low:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">void CS43L22_RST_Pin_Low(void)\n{\n\tGPIOD-&gt;BSRR=GPIO_BSRR_BR4;\n}\n\nvoid CS43L22_RST_Pin_High(void)\n{\n\tGPIOD-&gt;BSRR=GPIO_BSRR_BS4;\n}<\/pre><\/div>\n\n\n\n<p>Setting the pin low will reset the chip and high will release the chip from reset state.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>For the initialization of CS42L22:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">void CS43_Init(CS43_MODE outputMode)\n{\n\n\tCS43L22_RST_Pin_High();\n\n\t\/\/(2): Power down\n\tiData[1] = 0x01;\n\twrite_register(POWER_CONTROL1,iData);\n\n\t\/\/(3): Enable Right and Left headphones\n\tiData[1] =  (2 &lt;&lt; 6);  \/\/ PDN_HPB[0:1]  = 10 (HP-B always onCon)\n\tiData[1] |= (2 &lt;&lt; 4);  \/\/ PDN_HPA[0:1]  = 10 (HP-A always on)\n\tiData[1] |= (3 &lt;&lt; 2);  \/\/ PDN_SPKB[0:1] = 11 (Speaker B always off)\n\tiData[1] |= (3 &lt;&lt; 0);  \/\/ PDN_SPKA[0:1] = 11 (Speaker A always off)\n\twrite_register(POWER_CONTROL2,&amp;iData[1]);\n\n\t\/\/(4): Automatic clock detection\n\tiData[1] = (1 &lt;&lt; 7);\n\twrite_register(CLOCKING_CONTROL,&amp;iData[1]);\n\n\t\/\/(5): Interface control 1\n\tread_register(INTERFACE_CONTROL1, iData);\n\tiData[1] &amp;= (1 &lt;&lt; 5); \/\/ Clear all bits except bit 5 which is reserved\n\tiData[1] &amp;= ~(1 &lt;&lt; 7);  \/\/ Slave\n\tiData[1] &amp;= ~(1 &lt;&lt; 6);  \/\/ Clock polarity: Not inverted\n\tiData[1] &amp;= ~(1 &lt;&lt; 4);  \/\/ No DSP mode\n\tiData[1] &amp;= ~(1 &lt;&lt; 2);  \/\/ Left justified, up to 24 bit (default)\n\tiData[1] |= (1 &lt;&lt; 2);\n\tiData[1] |=  (3 &lt;&lt; 0);  \/\/ 16-bit audio word length for I2S interface\n\twrite_register(INTERFACE_CONTROL1,&amp;iData[1]);\n\n\n\t\/\/(6): Passthrough A settings\n\tread_register(PASSTHROUGH_A, &amp;iData[1]);\n\tiData[1] &amp;= 0xF0;      \/\/ Bits [4-7] are reserved\n\tiData[1] |=  (1 &lt;&lt; 0); \/\/ Use AIN1A as source for passthrough\n\twrite_register(PASSTHROUGH_A,&amp;iData[1]);\n\n\n\t\/\/(7): Passthrough B settings\n\tread_register(PASSTHROUGH_B, &amp;iData[1]);\n\tiData[1] &amp;= 0xF0;      \/\/ Bits [4-7] are reserved\n\tiData[1] |=  (1 &lt;&lt; 0); \/\/ Use AIN1B as source for passthrough\n\twrite_register(PASSTHROUGH_B,&amp;iData[1]);\n\n\n\t\/\/(8): Miscellaneous register settings\n\tread_register(MISCELLANEOUS_CONTRLS, &amp;iData[1]);\n\tif(outputMode == MODE_ANALOG)\n\t{\n\t\tiData[1] |=  (1 &lt;&lt; 7);   \/\/ Enable passthrough for AIN-A\n\t\tiData[1] |=  (1 &lt;&lt; 6);   \/\/ Enable passthrough for AIN-B\n\t\tiData[1] &amp;= ~(1 &lt;&lt; 5);   \/\/ Unmute passthrough on AIN-A\n\t\tiData[1] &amp;= ~(1 &lt;&lt; 4);   \/\/ Unmute passthrough on AIN-B\n\t\tiData[1] &amp;= ~(1 &lt;&lt; 3);   \/\/ Changed settings take affect immediately\n\t}\n\telse if(outputMode == MODE_I2S)\n\t{\n\t\tiData[1] = 0x02;\n\t}\n\twrite_register(MISCELLANEOUS_CONTRLS,&amp;iData[1]);\n\t\/\/(9): Unmute headphone and speaker\n\n\tread_register(PLAYBACK_CONTROL, &amp;iData[1]);\n\tiData[1] = 0x00;\n\twrite_register(PLAYBACK_CONTROL,&amp;iData[1]);\n\n\t\/\/(10): Set volume to default (0dB)\n\tiData[1] = 0x00;\n\twrite_register(PASSTHROUGH_VOLUME_A,&amp;iData[1]);\n\twrite_register(PASSTHROUGH_VOLUME_B,&amp;iData[1]);\n\twrite_register(PCM_VOLUME_A,&amp;iData[1]);\n\twrite_register(PCM_VOLUME_B,&amp;iData[1]);\n}<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>For selecting left, right or both channels:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">\/\/ Function(2): Enable Right and Left headphones\nvoid CS43_Enable_RightLeft(uint8_t side)\n{\n\tswitch (side)\n\t{\n\t\tcase 0:\n\t\t\tiData[1] =  (3 &lt;&lt; 6);  \/\/ PDN_HPB[0:1]  = 10 (HP-B always onCon)\n\t\t\tiData[1] |= (3 &lt;&lt; 4);  \/\/ PDN_HPA[0:1]  = 10 (HP-A always on)\n\t\t\tbreak;\n\t\tcase 1:\n\t\t\tiData[1] =  (2 &lt;&lt; 6);  \/\/ PDN_HPB[0:1]  = 10 (HP-B always onCon)\n\t\t\tiData[1] |= (3 &lt;&lt; 4);  \/\/ PDN_HPA[0:1]  = 10 (HP-A always on)\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\tiData[1] =  (3 &lt;&lt; 6);  \/\/ PDN_HPB[0:1]  = 10 (HP-B always onCon)\n\t\t\tiData[1] |= (2 &lt;&lt; 4);  \/\/ PDN_HPA[0:1]  = 10 (HP-A always on)\n\t\t\tbreak;\n\t\tcase 3:\n\t\t\tiData[1] =  (2 &lt;&lt; 6);  \/\/ PDN_HPB[0:1]  = 10 (HP-B always onCon)\n\t\t\tiData[1] |= (2 &lt;&lt; 4);  \/\/ PDN_HPA[0:1]  = 10 (HP-A always on)\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tbreak;\n\t}\n\tiData[1] |= (3 &lt;&lt; 2);  \/\/ PDN_SPKB[0:1] = 11 (Speaker B always off)\n\tiData[1] |= (3 &lt;&lt; 0);  \/\/ PDN_SPKA[0:1] = 11 (Speaker A always off)\n\twrite_register(POWER_CONTROL2,&amp;iData[1]);\n}<\/pre><\/div>\n\n\n\n<p><br>For Setting the volume:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">\/\/ Function(3): Set Volume Level\nvoid CS43_SetVolume(uint8_t volume)\n{\n\tint8_t tempVol = volume - 50;\n\ttempVol = tempVol*(127\/50);\n\tuint8_t myVolume =  (uint8_t )tempVol;\n\tiData[1] = myVolume;\n\twrite_register(PASSTHROUGH_VOLUME_A,&amp;iData[1]);\n\twrite_register(PASSTHROUGH_VOLUME_B,&amp;iData[1]);\n\n\tiData[1] = VOLUME_CONVERT_D(volume);\n\n\t\/* Set the Master volume *\/\n\twrite_register(CS43L22_REG_MASTER_A_VOL,&amp;iData[1]);\n\twrite_register(CS43L22_REG_MASTER_B_VOL,&amp;iData[1]);\n}<\/pre><\/div>\n\n\n\n<p>Start the DAC functionality:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">\/\/ Function(4): Start the Audio DAC\nvoid CS43_Start(void)\n{\n\t\/\/ Write 0x99 to register 0x00.\n\tiData[1] = 0x99;\n\twrite_register(CONFIG_00,&amp;iData[1]);\n\t\/\/ Write 0x80 to register 0x47.\n\tiData[1] = 0x80;\n\twrite_register(CONFIG_47,&amp;iData[1]);\n\t\/\/ Write '1'b to bit 7 in register 0x32.\n\tread_register(CONFIG_32, &amp;iData[1]);\n\tiData[1] |= 0x80;\n\twrite_register(CONFIG_32,&amp;iData[1]);\n\t\/\/ Write '0'b to bit 7 in register 0x32.\n\tread_register(CONFIG_32, &amp;iData[1]);\n\tiData[1] &amp;= ~(0x80);\n\twrite_register(CONFIG_32,&amp;iData[1]);\n\t\/\/ Write 0x00 to register 0x00.\n\tiData[1] = 0x00;\n\twrite_register(CONFIG_00,&amp;iData[1]);\n\t\/\/Set the &quot;Power Ctl 1&quot; register (0x02) to 0x9E\n\tiData[1] = 0x9E;\n\twrite_register(POWER_CONTROL1,&amp;iData[1]);\n}<\/pre><\/div>\n\n\n\n<p>For stoping the DAC:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">void CS43_Stop(void)\n{\n\tiData[1] = 0x01;\n\twrite_register(POWER_CONTROL1,&amp;iData[1]);\n}<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>Hence, the source code as following:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#include &quot;i2c.h&quot;\n#include &quot;CS43L22.h&quot;\n\n\nstatic uint8_t iData[2];\n\n\n\n\/\/(1): Functions definitions\n\/\/-------------- Static Functions ---------------\/\/\n\/\/ Function(1): Write to register\nstatic void write_register(uint8_t reg, uint8_t *data)\n{\n\tiData[0] = reg;\n\tiData[1] = data[0];\n\ti2c_writeByte(DAC_I2C_ADDR, (char)iData[0], (char)iData[1]);\n\n}\n\/\/ Function(2): Read from register\nstatic void read_register(uint8_t reg, uint8_t *data)\n{\n\tchar tempData=0;\n\ti2c_readByte(DAC_I2C_ADDR,(char)reg, &amp;tempData);\n\t*data=tempData;\n}\n\n\nvoid CS43L22_Pin_RST_Init(void)\n{\n\tRCC-&gt;AHB1ENR|=RCC_AHB1ENR_GPIODEN;\n\n\tGPIOD-&gt;MODER|=GPIO_MODER_MODE4_0;\n\tGPIOD-&gt;MODER&amp;=~GPIO_MODER_MODE4_1;\n}\n\nvoid CS43L22_RST_Pin_Low(void)\n{\n\tGPIOD-&gt;BSRR=GPIO_BSRR_BR4;\n}\n\nvoid CS43L22_RST_Pin_High(void)\n{\n\tGPIOD-&gt;BSRR=GPIO_BSRR_BS4;\n}\n\n\n\/\/-------------- Public Functions ----------------\/\/\n\/\/ Function(1): Initialisation\n\nvoid CS43_Init(CS43_MODE outputMode)\n{\n\n\tCS43L22_RST_Pin_High();\n\n\t\/\/(2): Power down\n\tiData[1] = 0x01;\n\twrite_register(POWER_CONTROL1,iData);\n\n\t\/\/(3): Enable Right and Left headphones\n\tiData[1] =  (2 &lt;&lt; 6);  \/\/ PDN_HPB[0:1]  = 10 (HP-B always onCon)\n\tiData[1] |= (2 &lt;&lt; 4);  \/\/ PDN_HPA[0:1]  = 10 (HP-A always on)\n\tiData[1] |= (3 &lt;&lt; 2);  \/\/ PDN_SPKB[0:1] = 11 (Speaker B always off)\n\tiData[1] |= (3 &lt;&lt; 0);  \/\/ PDN_SPKA[0:1] = 11 (Speaker A always off)\n\twrite_register(POWER_CONTROL2,&amp;iData[1]);\n\n\t\/\/(4): Automatic clock detection\n\tiData[1] = (1 &lt;&lt; 7);\n\twrite_register(CLOCKING_CONTROL,&amp;iData[1]);\n\n\t\/\/(5): Interface control 1\n\tread_register(INTERFACE_CONTROL1, iData);\n\tiData[1] &amp;= (1 &lt;&lt; 5); \/\/ Clear all bits except bit 5 which is reserved\n\tiData[1] &amp;= ~(1 &lt;&lt; 7);  \/\/ Slave\n\tiData[1] &amp;= ~(1 &lt;&lt; 6);  \/\/ Clock polarity: Not inverted\n\tiData[1] &amp;= ~(1 &lt;&lt; 4);  \/\/ No DSP mode\n\tiData[1] &amp;= ~(1 &lt;&lt; 2);  \/\/ Left justified, up to 24 bit (default)\n\tiData[1] |= (1 &lt;&lt; 2);\n\tiData[1] |=  (3 &lt;&lt; 0);  \/\/ 16-bit audio word length for I2S interface\n\twrite_register(INTERFACE_CONTROL1,&amp;iData[1]);\n\n\n\t\/\/(6): Passthrough A settings\n\tread_register(PASSTHROUGH_A, &amp;iData[1]);\n\tiData[1] &amp;= 0xF0;      \/\/ Bits [4-7] are reserved\n\tiData[1] |=  (1 &lt;&lt; 0); \/\/ Use AIN1A as source for passthrough\n\twrite_register(PASSTHROUGH_A,&amp;iData[1]);\n\n\n\t\/\/(7): Passthrough B settings\n\tread_register(PASSTHROUGH_B, &amp;iData[1]);\n\tiData[1] &amp;= 0xF0;      \/\/ Bits [4-7] are reserved\n\tiData[1] |=  (1 &lt;&lt; 0); \/\/ Use AIN1B as source for passthrough\n\twrite_register(PASSTHROUGH_B,&amp;iData[1]);\n\n\n\t\/\/(8): Miscellaneous register settings\n\tread_register(MISCELLANEOUS_CONTRLS, &amp;iData[1]);\n\tif(outputMode == MODE_ANALOG)\n\t{\n\t\tiData[1] |=  (1 &lt;&lt; 7);   \/\/ Enable passthrough for AIN-A\n\t\tiData[1] |=  (1 &lt;&lt; 6);   \/\/ Enable passthrough for AIN-B\n\t\tiData[1] &amp;= ~(1 &lt;&lt; 5);   \/\/ Unmute passthrough on AIN-A\n\t\tiData[1] &amp;= ~(1 &lt;&lt; 4);   \/\/ Unmute passthrough on AIN-B\n\t\tiData[1] &amp;= ~(1 &lt;&lt; 3);   \/\/ Changed settings take affect immediately\n\t}\n\telse if(outputMode == MODE_I2S)\n\t{\n\t\tiData[1] = 0x02;\n\t}\n\twrite_register(MISCELLANEOUS_CONTRLS,&amp;iData[1]);\n\t\/\/(9): Unmute headphone and speaker\n\n\tread_register(PLAYBACK_CONTROL, &amp;iData[1]);\n\tiData[1] = 0x00;\n\twrite_register(PLAYBACK_CONTROL,&amp;iData[1]);\n\n\t\/\/(10): Set volume to default (0dB)\n\tiData[1] = 0x00;\n\twrite_register(PASSTHROUGH_VOLUME_A,&amp;iData[1]);\n\twrite_register(PASSTHROUGH_VOLUME_B,&amp;iData[1]);\n\twrite_register(PCM_VOLUME_A,&amp;iData[1]);\n\twrite_register(PCM_VOLUME_B,&amp;iData[1]);\n}\n\n\/\/ Function(2): Enable Right and Left headphones\nvoid CS43_Enable_RightLeft(uint8_t side)\n{\n\tswitch (side)\n\t{\n\t\tcase 0:\n\t\t\tiData[1] =  (3 &lt;&lt; 6);  \/\/ PDN_HPB[0:1]  = 10 (HP-B always onCon)\n\t\t\tiData[1] |= (3 &lt;&lt; 4);  \/\/ PDN_HPA[0:1]  = 10 (HP-A always on)\n\t\t\tbreak;\n\t\tcase 1:\n\t\t\tiData[1] =  (2 &lt;&lt; 6);  \/\/ PDN_HPB[0:1]  = 10 (HP-B always onCon)\n\t\t\tiData[1] |= (3 &lt;&lt; 4);  \/\/ PDN_HPA[0:1]  = 10 (HP-A always on)\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\tiData[1] =  (3 &lt;&lt; 6);  \/\/ PDN_HPB[0:1]  = 10 (HP-B always onCon)\n\t\t\tiData[1] |= (2 &lt;&lt; 4);  \/\/ PDN_HPA[0:1]  = 10 (HP-A always on)\n\t\t\tbreak;\n\t\tcase 3:\n\t\t\tiData[1] =  (2 &lt;&lt; 6);  \/\/ PDN_HPB[0:1]  = 10 (HP-B always onCon)\n\t\t\tiData[1] |= (2 &lt;&lt; 4);  \/\/ PDN_HPA[0:1]  = 10 (HP-A always on)\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tbreak;\n\t}\n\tiData[1] |= (3 &lt;&lt; 2);  \/\/ PDN_SPKB[0:1] = 11 (Speaker B always off)\n\tiData[1] |= (3 &lt;&lt; 0);  \/\/ PDN_SPKA[0:1] = 11 (Speaker A always off)\n\twrite_register(POWER_CONTROL2,&amp;iData[1]);\n}\n\n\/\/ Function(3): Set Volume Level\nvoid CS43_SetVolume(uint8_t volume)\n{\n\tint8_t tempVol = volume - 50;\n\ttempVol = tempVol*(127\/50);\n\tuint8_t myVolume =  (uint8_t )tempVol;\n\tiData[1] = myVolume;\n\twrite_register(PASSTHROUGH_VOLUME_A,&amp;iData[1]);\n\twrite_register(PASSTHROUGH_VOLUME_B,&amp;iData[1]);\n\n\tiData[1] = VOLUME_CONVERT_D(volume);\n\n\t\/* Set the Master volume *\/\n\twrite_register(CS43L22_REG_MASTER_A_VOL,&amp;iData[1]);\n\twrite_register(CS43L22_REG_MASTER_B_VOL,&amp;iData[1]);\n}\n\n\/\/ Function(4): Start the Audio DAC\nvoid CS43_Start(void)\n{\n\t\/\/ Write 0x99 to register 0x00.\n\tiData[1] = 0x99;\n\twrite_register(CONFIG_00,&amp;iData[1]);\n\t\/\/ Write 0x80 to register 0x47.\n\tiData[1] = 0x80;\n\twrite_register(CONFIG_47,&amp;iData[1]);\n\t\/\/ Write '1'b to bit 7 in register 0x32.\n\tread_register(CONFIG_32, &amp;iData[1]);\n\tiData[1] |= 0x80;\n\twrite_register(CONFIG_32,&amp;iData[1]);\n\t\/\/ Write '0'b to bit 7 in register 0x32.\n\tread_register(CONFIG_32, &amp;iData[1]);\n\tiData[1] &amp;= ~(0x80);\n\twrite_register(CONFIG_32,&amp;iData[1]);\n\t\/\/ Write 0x00 to register 0x00.\n\tiData[1] = 0x00;\n\twrite_register(CONFIG_00,&amp;iData[1]);\n\t\/\/Set the &quot;Power Ctl 1&quot; register (0x02) to 0x9E\n\tiData[1] = 0x9E;\n\twrite_register(POWER_CONTROL1,&amp;iData[1]);\n}\n\nvoid CS43_Stop(void)\n{\n\tiData[1] = 0x01;\n\twrite_register(POWER_CONTROL1,&amp;iData[1]);\n}<\/pre><\/div>\n\n\n\n<p>Please refer to the datasheet from <a href=\"https:\/\/statics.cirrus.com\/pubs\/proDatasheet\/CS43L22_F2.pdf\" data-type=\"URL\" data-id=\"https:\/\/statics.cirrus.com\/pubs\/proDatasheet\/CS43L22_F2.pdf\" target=\"_blank\" rel=\"noreferrer noopener\">here<\/a> for more details about each register.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">21. Main Code:<\/h2>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#include &quot;delay.h&quot;\n#include &quot;stdlib.h&quot;\n#include &quot;i2s.h&quot;\n#include &quot;CS43L22.h&quot;\n#include &quot;i2c.h&quot;\n#include &quot;stdio.h&quot;\n#include &quot;math.h&quot;\n\n\n#define F_SAMPLE\t96000.0f\n#define F_OUT\t\t2000.0f\n#define PI \t\t\t3.14159f\n\n\nuint16_t dataI2S[100];\nfloat mySinVal;\nfloat sample_dt;\nuint16_t sample_N;\nuint16_t i_t;\n\n\n\n\nint main(void)\n{\n\tdelay_init(168000000);\n\n\ti2c_init();\n\n\tI2S3_Pins_Init();\n\tI2S3_Init();\n\n\n\tCS43L22_Pin_RST_Init();\n\tCS43_Init(MODE_I2S);\n\tCS43_SetVolume(100);\n\tCS43_Enable_RightLeft(CS43_RIGHT_LEFT);\n\tCS43_Start();\n\n\tsample_dt = F_OUT\/F_SAMPLE;\n\tsample_N = F_SAMPLE\/F_OUT;\n\n\tfor(uint16_t i=0; i&lt;sample_N; i++)\n\t{\n\t\tmySinVal = sinf(i*2*PI*sample_dt);\n\n\t\tdataI2S[i*2] = (mySinVal )*8000;    \/\/Right data (0 2 4 6 8 10 12)\n\n\t\tdataI2S[i*2 + 1] =(mySinVal )*8000; \/\/Left data  (1 3 5 7 9 11 13)\n\t}\n\n\tI2S_SendData_DMA(dataI2S, 100);\n\n\twhile(1)\n\t{\n\n\n\t}\n\n\n}<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">22. Source Code Download:<\/h2>\n\n\n\n<p><\/p>\n\n\n\n<p>You may download the source code from here.<\/p>\n\n\n\n<div class=\"wp-block-file\"><a href=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/06\/CS43L22.zip\">CS43L22<\/a><a href=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/06\/CS43L22.zip\" class=\"wp-block-file__button\" download>Download<\/a><\/div>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">23. Results:<\/h2>\n\n\n\n<p><\/p>\n\n\n\n<p>Since the main data shall generate sinewave with 2KHz, you should hear some loud noise from the headphone.<\/p>\n\n\n\n<p>By probing on of the channels, you should get the following:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"800\" height=\"480\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/06\/DS1Z_QuickPrint10.png\" alt=\"\" class=\"wp-image-2618\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/06\/DS1Z_QuickPrint10.png 800w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/06\/DS1Z_QuickPrint10-300x180.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/06\/DS1Z_QuickPrint10-768x461.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/06\/DS1Z_QuickPrint10-750x450.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/06\/DS1Z_QuickPrint10-400x240.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/06\/DS1Z_QuickPrint10-250x150.png 250w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><\/figure>\n\n\n\n<p>As you can see, we got 2KHz sinewave (almost due to approximation).<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Happy coding \ud83d\ude09<\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In the previous guide (here), we were able to transmit data over I2S using DMA, in this guide, we shall initialize the CS43L22 which is stereo DAC. In this guide, we shall cover the following: Enabling circular mode for DMA. Header file development. Source file development. Main code. Source code download. Results. 18. Enabling Circular [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2,11,12],"tags":[],"class_list":["post-2612","post","type-post","status-publish","format-standard","hentry","category-embedded-systems","category-peripheral-drivers","category-stm32"],"_links":{"self":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/2612"}],"collection":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2612"}],"version-history":[{"count":2,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/2612\/revisions"}],"predecessor-version":[{"id":2619,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/2612\/revisions\/2619"}],"wp:attachment":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2612"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2612"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2612"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}