{"id":1221,"date":"2022-09-25T08:25:04","date_gmt":"2022-09-25T08:25:04","guid":{"rendered":"https:\/\/blog.embeddedexpert.io\/?p=1221"},"modified":"2022-09-25T08:25:08","modified_gmt":"2022-09-25T08:25:08","slug":"getting-started-with-stm32l053-i2c-write-mode-with-dma","status":"publish","type":"post","link":"https:\/\/blog.embeddedexpert.io\/?p=1221","title":{"rendered":"Getting started with STM32L053: I2C Write Mode with DMA"},"content":{"rendered":"\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img decoding=\"async\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/1200px-I%C2%B2C_bus_logo.svg_-273x300.png\" alt=\"\" class=\"wp-image-417\" \/><\/figure><\/div>\n\n\n\n<p>In the previous guide(<a rel=\"noreferrer noopener\" href=\"https:\/\/blog.embeddedexpert.io\/?p=1077\" data-type=\"URL\" data-id=\"https:\/\/blog.embeddedexpert.io\/?p=1077\" target=\"_blank\">here<\/a>) we saw how to configure the I2C to write to a slave device, n this guide, we shall see how to configure I2C in STM32L053 to write to a specific register of an I2C device (DS3231 in this case) using DMA.<\/p>\n\n\n\n<p><\/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>I2C with DMA configuration.<\/li><li>I2C write DMA.<\/li><li>Code.<\/li><li>Demo.<\/li><\/ul>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">1. I2C with DMA Configuration:<\/h2>\n\n\n\n<p>We start off with configuring I2C as shown in the previous guide:<\/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;}\">\tRCC-&gt;IOPENR|=RCC_IOPENR_GPIOBEN;\n\tGPIOB-&gt;MODER&amp;=~(GPIO_MODER_MODE8|GPIO_MODER_MODE9);\n\tGPIOB-&gt;MODER|=GPIO_MODER_MODE8_1|GPIO_MODER_MODE9_1;\n\tGPIOB-&gt;OTYPER|=GPIO_OTYPER_OT_8|GPIO_OTYPER_OT_9;\n\tGPIOB-&gt;OSPEEDR|=GPIO_OSPEEDER_OSPEED8_0|GPIO_OSPEEDER_OSPEED8_1|GPIO_OSPEEDER_OSPEED9_0|GPIO_OSPEEDER_OSPEED9_1;\n\tGPIOB-&gt;AFR[1]|=(AF04&lt;&lt;0)|(AF04&lt;&lt;4);\n\n\tRCC-&gt;APB1ENR|=RCC_APB1ENR_I2C1EN;\n\tI2C1-&gt;CR1 &amp;=~I2C_CR1_PE;\n\tI2C1-&gt;TIMINGR=timing;\n<\/pre><\/div>\n\n\n\n<p>After that, we configure DMA.<\/p>\n\n\n\n<p>In order to configure the DMA, we need to enable clock access to the DMA1. <\/p>\n\n\n\n<p>Since STM32L053 has only single DMA and it is connected to AHB Bus, we can enable clock access to DMA1 as following:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"642\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/08\/Screen-Shot-2022-08-17-at-7.26.00-AM-1024x642.png\" alt=\"\" class=\"wp-image-1157\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/08\/Screen-Shot-2022-08-17-at-7.26.00-AM-1024x642.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/08\/Screen-Shot-2022-08-17-at-7.26.00-AM-300x188.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/08\/Screen-Shot-2022-08-17-at-7.26.00-AM-768x482.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/08\/Screen-Shot-2022-08-17-at-7.26.00-AM-1536x963.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/08\/Screen-Shot-2022-08-17-at-7.26.00-AM-2048x1284.png 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/08\/Screen-Shot-2022-08-17-at-7.26.00-AM-1150x721.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/08\/Screen-Shot-2022-08-17-at-7.26.00-AM-750x470.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/08\/Screen-Shot-2022-08-17-at-7.26.00-AM-400x251.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/08\/Screen-Shot-2022-08-17-at-7.26.00-AM-250x157.png 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\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;}\">RCC-&gt;AHBENR|=RCC_AHBENR_DMA1EN;<\/pre><\/div>\n\n\n\n<p>Now, we need to check which channel is responsible for I2C1_TX.<\/p>\n\n\n\n<p>From the reference manual,  we can check DMA request for each channel:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"384\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-25-at-10.59.43-AM-1024x384.png\" alt=\"\" class=\"wp-image-1222\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-25-at-10.59.43-AM-1024x384.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-25-at-10.59.43-AM-300x113.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-25-at-10.59.43-AM-768x288.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-25-at-10.59.43-AM-1536x576.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-25-at-10.59.43-AM-1150x431.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-25-at-10.59.43-AM-750x281.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-25-at-10.59.43-AM-400x150.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-25-at-10.59.43-AM-250x94.png 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-25-at-10.59.43-AM.png 1786w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>We can see that we have channel2 and channel6 for I2C1_TX, in this guide, channel6 shall be used.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>After enabling clock access to DMA1, we need configure channel6 with the following parameters:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Memory increment mode.<\/li><li>Direction read from memory.<\/li><li>Transfer complete interrupt enable.<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"477\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-25-at-11.03.35-AM-1024x477.png\" alt=\"\" class=\"wp-image-1223\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-25-at-11.03.35-AM-1024x477.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-25-at-11.03.35-AM-300x140.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-25-at-11.03.35-AM-768x357.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-25-at-11.03.35-AM-1536x715.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-25-at-11.03.35-AM-1150x535.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-25-at-11.03.35-AM-750x349.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-25-at-11.03.35-AM-400x186.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-25-at-11.03.35-AM-250x116.png 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-25-at-11.03.35-AM.png 1796w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\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;}\">DMA1_Channel6-&gt;CCR |=DMA_CCR_MINC|DMA_CCR_DIR|DMA_CCR_TCIE;<\/pre><\/div>\n\n\n\n<p>Set the peripheral address to be the TXDR:<\/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;}\">DMA1_Channel6-&gt;CPAR= (uint32_t)&amp;I2C1-&gt;TXDR;<\/pre><\/div>\n\n\n\n<p>Enable the DMA1_Channel interrupt in NVIC:<\/p>\n\n\n\n<p>Channel4 through 7 share the same interrupt handler<\/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;}\">NVIC_EnableIRQ(DMA1_Channel4_5_6_7_IRQn);<\/pre><\/div>\n\n\n\n<p>Set Channel6 to be I2C:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"424\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-25-at-11.07.34-AM-1024x424.png\" alt=\"\" class=\"wp-image-1224\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-25-at-11.07.34-AM-1024x424.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-25-at-11.07.34-AM-300x124.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-25-at-11.07.34-AM-768x318.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-25-at-11.07.34-AM-1536x636.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-25-at-11.07.34-AM-1150x476.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-25-at-11.07.34-AM-750x311.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-25-at-11.07.34-AM-400x166.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-25-at-11.07.34-AM-250x104.png 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-25-at-11.07.34-AM.png 1796w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\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 DMA_CSELR  (*(volatile unsigned int *)(0x400200a8))\nDMA_CSELR|=(0x06&lt;&lt;20);<\/pre><\/div>\n\n\n\n<p>Finally, enable the I2C:<\/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;}\">I2C1-&gt;CR1 |=I2C_CR1_PE;<\/pre><\/div>\n\n\n\n<p>Hence the initializing function:<\/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 i2c_init(uint32_t timing)\n{\n\tRCC-&gt;IOPENR|=RCC_IOPENR_GPIOBEN;\n\tGPIOB-&gt;MODER&amp;=~(GPIO_MODER_MODE8|GPIO_MODER_MODE9);\n\tGPIOB-&gt;MODER|=GPIO_MODER_MODE8_1|GPIO_MODER_MODE9_1;\n\tGPIOB-&gt;OTYPER|=GPIO_OTYPER_OT_8|GPIO_OTYPER_OT_9;\n\tGPIOB-&gt;OSPEEDR|=GPIO_OSPEEDER_OSPEED8_0|GPIO_OSPEEDER_OSPEED8_1|GPIO_OSPEEDER_OSPEED9_0|GPIO_OSPEEDER_OSPEED9_1;\n\tGPIOB-&gt;AFR[1]|=(AF04&lt;&lt;0)|(AF04&lt;&lt;4);\n\n\tRCC-&gt;APB1ENR|=RCC_APB1ENR_I2C1EN;\n\tI2C1-&gt;CR1 &amp;=~I2C_CR1_PE;\n\tI2C1-&gt;TIMINGR=timing;\n\n\n\tRCC-&gt;AHBENR|=RCC_AHBENR_DMA1EN;\n\tDMA1_Channel6-&gt;CCR |=DMA_CCR_MINC|DMA_CCR_DIR|DMA_CCR_TCIE;\n\tDMA1_Channel6-&gt;CPAR= (uint32_t)&amp;I2C1-&gt;TXDR;\n\tNVIC_EnableIRQ(DMA1_Channel4_5_6_7_IRQn);\n\tDMA_CSELR|=(0x06&lt;&lt;20);\n\n\tI2C1-&gt;CR1 |=I2C_CR1_PE;\n\n\n\n}<\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">2. I2C Write DMA:<\/h2>\n\n\n\n<p>We shall declare a function that takes three arguments: <\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Slave address<\/li><li>Buffer that holds the data to be written.<\/li><li>length of the data.<\/li><\/ul>\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 i2c_write_dma(uint8_t slav_add, uint8_t *data, uint16_t length)<\/pre><\/div>\n\n\n\n<p>Within the function, make sure that the i2c is enabled:<\/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;}\">\/*Enable I2C*\/\n\t\tI2C1-&gt;CR1 |=I2C_CR1_PE;<\/pre><\/div>\n\n\n\n<p>Enable TXDMA from CR1:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"491\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-25-at-11.12.39-AM-1024x491.png\" alt=\"\" class=\"wp-image-1225\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-25-at-11.12.39-AM-1024x491.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-25-at-11.12.39-AM-300x144.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-25-at-11.12.39-AM-768x368.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-25-at-11.12.39-AM-1536x736.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-25-at-11.12.39-AM-1150x551.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-25-at-11.12.39-AM-750x359.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-25-at-11.12.39-AM-400x192.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-25-at-11.12.39-AM-250x120.png 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-25-at-11.12.39-AM.png 1824w\" 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;}\">\/*Enable DMA_TX*\/\n\t\tI2C1-&gt;CR1|=I2C_CR1_TXDMAEN;<\/pre><\/div>\n\n\n\n<p>Then the following:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Set the slave address.<\/li><li>Set the address to be 7-bit mode.<\/li><li>Length of the data.<\/li><li>Mode to be write mode.<\/li><li>Enable Auto end.<\/li><\/ul>\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;}\">\/*Set slave address*\/\n\t\tI2C1-&gt;CR2=(slav_add&lt;&lt;1);\n\t\t\/*7-bit addressing*\/\n\t\tI2C1-&gt;CR2&amp;=~I2C_CR2_ADD10;\n\t\t\/*Set number to transfer to length for write operation*\/\n\t\tI2C1-&gt;CR2|=(length&lt;&lt;I2C_CR2_NBYTES_Pos);\n\t\t\/*Set the mode to write mode*\/\n\t\tI2C1-&gt;CR2&amp;=~I2C_CR2_RD_WRN;\n\t\t\/*hardware end*\/\n\t\tI2C1-&gt;CR2|=I2C_CR2_AUTOEND;<\/pre><\/div>\n\n\n\n<p>Now, for the DMA:<\/p>\n\n\n\n<p>Disable the channel and wait until the channel is disabled:<\/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\tDMA1_Channel6-&gt;CCR&amp;=~DMA_CCR_EN;\n\t\twhile(DMA1_Channel6-&gt;CCR &amp;DMA_CCR_EN);<\/pre><\/div>\n\n\n\n<p>Set the length:<\/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;}\">DMA1_Channel6-&gt;CNDTR=length;<\/pre><\/div>\n\n\n\n<p>Set the memory address to be the buffer:<\/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;}\">DMA1_Channel6-&gt;CMAR=(uint32_t)data;<\/pre><\/div>\n\n\n\n<p>Enable the DMA channel:<\/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;}\">DMA1_Channel6-&gt;CCR|=DMA_CCR_EN;<\/pre><\/div>\n\n\n\n<p>Generate the start:<\/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;}\">\/*Generate start*\/\nI2C1-&gt;CR2|=I2C_CR2_START;<\/pre><\/div>\n\n\n\n<p>Wait until the tx_done is set to 1 and reset it after that:<\/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;}\">while(tx_done==0);\ntx_done=0;<\/pre><\/div>\n\n\n\n<p>For the interrupt handler of the DMA:<\/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;}\">\n\nvoid DMA1_Channel4_7_IRQHandler(void)\n\t{\n\n\tif(DMA1-&gt;ISR &amp; DMA_ISR_TCIF6)\n\t\t{\n\t\ttx_done=1;\n\t\tDMA1-&gt;IFCR=DMA_IFCR_CTCIF6;\n\t\t}\n\t}\n<\/pre><\/div>\n\n\n\n<p>Hence, the i2c_write_dma function is 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;}\">\nvoid i2c_write_dma(uint8_t slav_add, uint8_t *data, uint16_t length)\n\t{\n\t\/*Enable I2C*\/\n\t\tI2C1-&gt;CR1 |=I2C_CR1_PE;\n\t\t\/*Enable DMA_TX*\/\n\t\tI2C1-&gt;CR1|=I2C_CR1_TXDMAEN;\n\t\t\/*Set slave address*\/\n\t\tI2C1-&gt;CR2=(slav_add&lt;&lt;1);\n\t\t\/*7-bit addressing*\/\n\t\tI2C1-&gt;CR2&amp;=~I2C_CR2_ADD10;\n\t\t\/*Set number to transfer to length for write operation*\/\n\t\tI2C1-&gt;CR2|=(length&lt;&lt;I2C_CR2_NBYTES_Pos);\n\t\t\/*Set the mode to write mode*\/\n\t\tI2C1-&gt;CR2&amp;=~I2C_CR2_RD_WRN;\n\t\t\/*hardware end*\/\n\t\tI2C1-&gt;CR2|=I2C_CR2_AUTOEND;\n\n\t\tDMA1_Channel6-&gt;CCR&amp;=~DMA_CCR_EN;\n\t\twhile(DMA1_Channel6-&gt;CCR &amp;DMA_CCR_EN);\n\t\tDMA1_Channel6-&gt;CNDTR=length;\n\t\tDMA1_Channel6-&gt;CMAR=(uint32_t)data;\n\t\tDMA1_Channel6-&gt;CCR|=DMA_CCR_EN;\n\t\t\/*Generate start*\/\n\t\tI2C1-&gt;CR2|=I2C_CR2_START;\n\n\t\td\n\t\t\/\/I2C1-&gt;CR1 &amp;=~I2C_CR1_PE;\n\t}<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">3. Code:<\/h2>\n\n\n\n<p>For testing purposes, we shall use DS3231 and inside the main.c:<\/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;uart.h&quot;\n#include &quot;stdio.h&quot;\n#include &quot;stdlib.h&quot;\n#define slave_add (0x68)\n\n\nuint8_t data_rec[3],data_send[4];\n\nint bcd_to_decimal(unsigned char x) {\n    return x - 6 * (x &gt;&gt; 4);\n}\n\nint main()\n\t{\n\tuart_init();\n\ti2c_init(0x00708);\n\twhile(1)\n\t\t{\n\t\ti2_read(slave_add,0x00,data_rec,3);\n\t\t\tfor (volatile int i=0;i&lt;3;i++)\n\t\t\t\t{\n\t\t\t\t\tdata_rec[i]=bcd_to_decimal(data_rec[i]);\n\t\t\t\t}\n\t\t\tif(data_rec[0]!=0){\n\t\t\t\tif(data_rec[0]%5==0){\n\t\t\t\t\t\tdata_send[0]=0x00;\n\t\t\t\t\t\tdata_send[1]=0x00;\n\t\t\t\t\t\tdata_send[2]=(rand() % 5);\n\t\t\t\t\t\tdata_send[3]=(rand() % 5);\n\t\t\t\t\t\ti2c_write_dma(slave_add,data_send,4);\n\t\t\t\t\t\t}}\n\t\t\tprintf(&quot;rtc data %d %d %d\\r\\n&quot;,data_rec[2],data_rec[1],data_rec[0]);\n\t\t\tfor (int i=0;i&lt;10000;i++);\n\n\t\t}\n\n\t}\n<\/pre><\/div>\n\n\n\n<p>You may download the code from here:<\/p>\n\n\n\n<div class=\"wp-block-file\"><a href=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/09\/I2C_STM32L0_DMA.zip\">I2C_STM32L0_DMA<\/a><a href=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/09\/I2C_STM32L0_DMA.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\">4. Demo:<\/h2>\n\n\n\n<p>Open serial terminal and set the buadrate to be 9600 and you should get this:<\/p>\n\n\n\n<p><\/p>\n\n\n\n<figure class=\"wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"I2C Demo on STM32L052 Nucleo-64\" width=\"1170\" height=\"658\" src=\"https:\/\/www.youtube.com\/embed\/i6rMqb1sXus?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen><\/iframe>\n<\/div><\/figure>\n\n\n\n<p>Happy coding \ud83d\ude42 <\/p>\n","protected":false},"excerpt":{"rendered":"<p>In the previous guide(here) we saw how to configure the I2C to write to a slave device, n this guide, we shall see how to configure I2C in STM32L053 to write to a specific register of an I2C device (DS3231 in this case) using DMA. In this guide, we shall cover the following: I2C with [&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-1221","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\/1221"}],"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=1221"}],"version-history":[{"count":1,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/1221\/revisions"}],"predecessor-version":[{"id":1227,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/1221\/revisions\/1227"}],"wp:attachment":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1221"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1221"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1221"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}