{"id":442,"date":"2021-09-23T05:30:25","date_gmt":"2021-09-23T05:30:25","guid":{"rendered":"https:\/\/blog.embeddedexpert.io\/?p=442"},"modified":"2021-09-23T05:30:28","modified_gmt":"2021-09-23T05:30:28","slug":"working-with-stm32-and-uart-part-5-receiving-characters-using-dma","status":"publish","type":"post","link":"https:\/\/blog.embeddedexpert.io\/?p=442","title":{"rendered":"Working with STM32 and UART part 5: Receiving Characters using DMA"},"content":{"rendered":"\n<p>In pervious guides, we took look how to send string using DMA (<a rel=\"noreferrer noopener\" href=\"https:\/\/blog.embeddedexpert.io\/?p=409\" data-type=\"URL\" data-id=\"https:\/\/blog.embeddedexpert.io\/?p=409\" target=\"_blank\">here<\/a>), and how to receive characters using interrupt(<a rel=\"noreferrer noopener\" href=\"https:\/\/blog.embeddedexpert.io\/?p=347\" data-type=\"URL\" data-id=\"https:\/\/blog.embeddedexpert.io\/?p=347\" target=\"_blank\">here<\/a>). In this guide, we shall use DMA to receive 5 characters and echo back the received character using DMA also.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"441\" height=\"259\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/UART-BUS-between-two-devices-2.jpg\" alt=\"\" class=\"wp-image-348\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/UART-BUS-between-two-devices-2.jpg 441w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/UART-BUS-between-two-devices-2-300x176.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/UART-BUS-between-two-devices-2-400x235.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/UART-BUS-between-two-devices-2-250x147.jpg 250w\" sizes=\"(max-width: 441px) 100vw, 441px\" \/><figcaption>UART<\/figcaption><\/figure><\/div>\n\n\n\n<p>In this guide, we will cover the following:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Configure UART for full duplex (TX and RX).<\/li><li>Code&nbsp;<\/li><li>Demo<\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">1.1 Configure UART for full duplex with DMA&nbsp;<\/h2>\n\n\n\n<p>In part 1 we discussed how to set the uart to send a single character, we shall use the same initialization sequence.<\/p>\n\n\n\n<p>We started by enabling clock access to USART2 and GPIOA port<\/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;}\">RCC-&gt;APB1ENR|=RCC_APB1ENR_USART2EN;\nRCC-&gt;AHB1ENR|=RCC_AHB1ENR_GPIOAEN;<\/pre><\/div>\n\n\n\n<p>From part one, we concluded that PA2 is the TX pin and PA3 is the RX pin. Hence, we configure them as alternate function and which alternate function 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;}\">GPIOA-&gt;MODER|=(1&lt;&lt;5);\/\/set bit5\nGPIOA-&gt;MODER&amp;=~(1&lt;&lt;4);\/\/reset bit4\n\nGPIOA-&gt;MODER|=(1&lt;&lt;7);\/\/set bit7\nGPIOA-&gt;MODER&amp;=~(1&lt;&lt;6);\/\/reset bit6\n\nGPIOA-&gt;AFR[0]=0x07700; \/\/ALT7 for UART2 (PA2 and PA3)<\/pre><\/div>\n\n\n\n<p>Now we need to configure the UART<\/p>\n\n\n\n<p>We starting by setting the baud rate to 9600 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;}\">USART2-&gt;BRR  = 0x0681;    \/\/9600 @16MHz<\/pre><\/div>\n\n\n\n<p>Then we enable the TX and RX of the UART as following<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"282\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-23-at-7.56.07-AM-1024x282.png\" alt=\"\" class=\"wp-image-443\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-23-at-7.56.07-AM-1024x282.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-23-at-7.56.07-AM-300x83.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-23-at-7.56.07-AM-768x211.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-23-at-7.56.07-AM-1536x423.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-23-at-7.56.07-AM-2048x564.png 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-23-at-7.56.07-AM-1150x317.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-23-at-7.56.07-AM-750x207.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-23-at-7.56.07-AM-400x110.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-23-at-7.56.07-AM-250x69.png 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><figcaption>USART_CR1<\/figcaption><\/figure><\/div>\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;}\">USART2-&gt;CR1|=USART_CR1_TE|USART_CR1_RE;<\/pre><\/div>\n\n\n\n<p>Then enable DMA_TX and DMA_RX in CR3<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"282\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-23-at-7.59.28-AM-1024x282.png\" alt=\"\" class=\"wp-image-444\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-23-at-7.59.28-AM-1024x282.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-23-at-7.59.28-AM-300x83.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-23-at-7.59.28-AM-768x211.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-23-at-7.59.28-AM-1536x423.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-23-at-7.59.28-AM-2048x564.png 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-23-at-7.59.28-AM-1150x317.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-23-at-7.59.28-AM-750x207.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-23-at-7.59.28-AM-400x110.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-23-at-7.59.28-AM-250x69.png 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure><\/div>\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;}\">USART2-&gt;CR3|=USART_CR3_DMAR|USART_CR3_DMAT;<\/pre><\/div>\n\n\n\n<p>Then from CR1 we enable transfer complete interrupt 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;}\">USART2-&gt;CR1|=USART_CR1_TCIE;<\/pre><\/div>\n\n\n\n<p>And finally enable UART from CR1<\/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;}\">USART2-&gt;CR1|=USART_CR1_UE;<\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">1.2 Configure DMA<\/h2>\n\n\n\n<p>For UART DMA transmission, please refer to part 4 of the UART guide (<a rel=\"noreferrer noopener\" href=\"https:\/\/blog.embeddedexpert.io\/?p=409\" data-type=\"URL\" data-id=\"https:\/\/blog.embeddedexpert.io\/?p=409\" target=\"_blank\">here<\/a>).<\/p>\n\n\n\n<p>In order to configure DMA to receive data, we need to find which stream and channel of UART_RX is connected to.<\/p>\n\n\n\n<p>From image below, we can see USART2_RX is stream5 channel 4<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"550\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-23-at-8.10.40-AM-1024x550.png\" alt=\"\" class=\"wp-image-447\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-23-at-8.10.40-AM-1024x550.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-23-at-8.10.40-AM-300x161.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-23-at-8.10.40-AM-768x413.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-23-at-8.10.40-AM-1536x826.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-23-at-8.10.40-AM-2048x1101.png 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-23-at-8.10.40-AM-1150x618.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-23-at-8.10.40-AM-750x403.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-23-at-8.10.40-AM-400x215.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-23-at-8.10.40-AM-250x134.png 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>We start of by enabling clock to DMA 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;}\">RCC-&gt;AHB1ENR |= RCC_AHB1ENR_DMA1EN;<\/pre><\/div>\n\n\n\n<p>Then disable the current DMA Stream 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\tDMA1_Stream5-&gt;CR &amp;= ~1;         \/* disable DMA1 Stream 5 *\/\n\t\twhile (DMA1_Stream5-&gt;CR &amp; 1) {} \/* wait until DMA1 Stream 5 is disabled *\/<\/pre><\/div>\n\n\n\n<p>clear all interrupt for Stream5<\/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-&gt;HIFCR = 0x00003F00;       \/* clear all interrupt flags of Stream 5 *\/<\/pre><\/div>\n\n\n\n<p>Set the peripheral to be UART2-&gt;DR, memory address and number of transfer 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;}\">DMA1_Stream5-&gt;PAR =(unsigned int)&amp;USART2-&gt;DR;\n    DMA1_Stream5-&gt;M0AR = (unsigned int)(d);\n    DMA1_Stream5-&gt;NDTR = sizeof(d);<\/pre><\/div>\n\n\n\n<p>Next we set the following<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>set to channel 4<\/li><li>Memory and peripheral size to 8-bit<\/li><li>Memory increment<\/li><li>Circular mode<\/li><li>Direction peripheral to memory<\/li><li>Transfer complete interrupt<\/li><li>Enable the stream<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"360\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-23-at-8.17.35-AM-1024x360.png\" alt=\"\" class=\"wp-image-448\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-23-at-8.17.35-AM-1024x360.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-23-at-8.17.35-AM-300x106.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-23-at-8.17.35-AM-768x270.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-23-at-8.17.35-AM-1536x541.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-23-at-8.17.35-AM-2048x721.png 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-23-at-8.17.35-AM-1150x405.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-23-at-8.17.35-AM-750x264.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-23-at-8.17.35-AM-400x141.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-23-at-8.17.35-AM-250x88.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;}\">DMA1_Stream5-&gt;CR =(1&lt;&lt;27);\n\t\tDMA1_Stream5-&gt;CR|=(1&lt;&lt;10)|(1&lt;&lt;8)|(1&lt;&lt;4);\n\t\tDMA1_Stream5-&gt;CR|=(1&lt;&lt;0);\n\t\tNVIC_EnableIRQ(DMA1_Stream5_IRQn);  \/* DMA interrupt enable at NVIC *\/<\/pre><\/div>\n\n\n\n<p>Stream 5 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;}\">void DMA1_Stream5_IRQHandler(void)\n\t\t{\n\t\tif((DMA1-&gt;HISR)&amp;(1&lt;&lt;11)) \/\/DMA receive complete\n\t\t\t{\n\t\t\tdone_rec=1; \/\/set receive data to \n\t\t\tDMA1-&gt;HIFCR|=(1&lt;&lt;11);\n\t\t\t}\n\t\t}<\/pre><\/div>\n\n\n\n<p>in the while loop, if the received data completed, echo back the received data<\/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;}\">\tif(done_rec==1){\n\t\tsprintf(message,&quot;Received characters are %s \\r\\n&quot;,d);\n\t\tdone_rec=0;\n        done = 0;               \/* clear done flag *\/\n        DMA1_Stream6_setup((unsigned int)message, (unsigned int)&amp;USART2-&gt;DR, strlen(message));\n\t\t\t\twhile (done == 0) {}    \/* wait until DMA data transfer is done *\/<\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">2 Code<\/h2>\n\n\n\n<p>Here is the full code<\/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;stm32f4xx.h&quot;                  \/\/ Device header\n#include &quot;string.h&quot;\n#include &quot;stdio.h&quot;\nvoid USART2_init(void);\nvoid DMA1_init(void);\nvoid DMA1_Stream6_setup(unsigned int src, unsigned int dst, int len);\nvoid DMA1_Stream5_setup();\n\nint done = 1;\nint done_rec=0;\nchar d[5];\nchar message [100]={'\\0'};\n    \nint main (void) {\n\t\t\t\n  USART2_init();\n  DMA1_init();\n  DMA1_Stream5_setup();\n\tsprintf(message,&quot;started\\r\\n&quot;);\n\t DMA1_Stream6_setup((unsigned int)message, (unsigned int)&amp;USART2-&gt;DR, strlen(message));\n\twhile (done == 0) {}    \/* wait until DMA data transfer is done *\/\t\n\t\n\t\n\t\n    while (1) {\n\t\t\t\n\tif(done_rec==1){\n\t\tsprintf(message,&quot;Received characters are %s \\r\\n&quot;,d);\n\t\tdone_rec=0;\n        done = 0;               \/* clear done flag *\/\n        DMA1_Stream6_setup((unsigned int)message, (unsigned int)&amp;USART2-&gt;DR, strlen(message));\n\t\t\t\twhile (done == 0) {}    \/* wait until DMA data transfer is done *\/\n\t\t\t\t\n    }\n\t\t}\n}\n\nvoid USART2_init (void) {\n    RCC-&gt;AHB1ENR |= 1;          \/* enable GPIOA clock *\/\n    RCC-&gt;APB1ENR |= 0x20000;    \/* enable USART2 clock *\/\n\n\t\tGPIOA-&gt;AFR[0]=0x07700; \/\/ALT7 for UART2\n\t\tGPIOA-&gt;MODER|=0x0080;  \/\/enable PA3 as alternate function\n\t\tGPIOA-&gt;MODER|=0x0020; \/\/enable PA2 as alterate fuction\n\n    USART2-&gt;BRR = 0x0683;       \/* 9600 baud @ 16 MHz *\/\n    USART2-&gt;CR1 = 0x0008|(1&lt;&lt;2);       \/* enable Tx, 8-bit data *\/\n    USART2-&gt;CR2 = 0x0000;       \/* 1 stop bit *\/\n    USART2-&gt;CR3 = 0x0000;       \/* no flow control *\/\n    USART2-&gt;CR1 |= 0x2000;      \/* enable USART2 *\/\n    USART2-&gt;CR3 |= (1&lt;&lt;7)|(1&lt;&lt;6);  \/* enable USART2 TX\/RX DMA *\/\n    USART2-&gt;SR = ~0x40;         \/* clear TC flag *\/\n    USART2-&gt;CR1 |= 0x0040;      \/* enable transmit complete interrupt *\/\n\n    NVIC_EnableIRQ(USART2_IRQn);    \/* USART2 interrupt enable at NVIC *\/\n}\n\n\nvoid DMA1_init(void) {\n    RCC-&gt;AHB1ENR |= RCC_AHB1ENR_DMA1EN;     \/* DMA controller clock enable *\/\n    DMA1-&gt;HIFCR = 0x003F0000;       \/* clear all interrupt flags of Stream 6 *\/\n    NVIC_EnableIRQ(DMA1_Stream6_IRQn);  \/* DMA interrupt enable at NVIC *\/\n}\n\nvoid DMA1_Stream5_setup()\n\n\t{\n\t\tRCC-&gt;AHB1ENR |= RCC_AHB1ENR_DMA1EN;\n\t\tDMA1_Stream5-&gt;CR &amp;= DMA_SxCR_EN;         \/* disable DMA1 Stream 5 *\/\n\t\twhile (DMA1_Stream5-&gt;CR &amp; 1) {} \/* wait until DMA1 Stream 5 is disabled *\/\n\t\tDMA1-&gt;HIFCR = 0x00003F00;       \/* clear all interrupt flags of Stream 5 *\/\n\t\tDMA1_Stream5-&gt;PAR =(unsigned int)&amp;USART2-&gt;DR;\n    DMA1_Stream5-&gt;M0AR = (unsigned int)(d);\n    DMA1_Stream5-&gt;NDTR = sizeof(d);\n\t\tDMA1_Stream5-&gt;CR =(1&lt;&lt;27);\n\t\tDMA1_Stream5-&gt;CR|=(1&lt;&lt;10)|(1&lt;&lt;8)|(1&lt;&lt;4);\n\t\tDMA1_Stream5-&gt;CR|=(1&lt;&lt;0);\n\t\tNVIC_EnableIRQ(DMA1_Stream5_IRQn);  \/* DMA interrupt enable at NVIC *\/\n\t\t\n\t}\n\n\n\nvoid DMA1_Stream6_setup(unsigned int src, unsigned int dst, int len) {\n\t\n\t\tUSART2-&gt;SR &amp;= ~USART_SR_TC;          \/* clear UART transmit complete interrupt flag *\/\n\t\n    DMA1_Stream6-&gt;CR &amp;= ~1;         \/* disable DMA1 Stream 6 *\/\n    while (DMA1_Stream6-&gt;CR &amp; 1) {} \/* wait until DMA1 Stream 6 is disabled *\/\n    DMA1-&gt;HIFCR = 0x003F0000;       \/* clear all interrupt flags of Stream 6 *\/\n    DMA1_Stream6-&gt;PAR = dst;\n    DMA1_Stream6-&gt;M0AR = src;\n    DMA1_Stream6-&gt;NDTR = len;\n    DMA1_Stream6-&gt;CR = 0x08000000;  \/* USART2_TX on DMA1 Stream6 Channel 4 *\/\n    DMA1_Stream6-&gt;CR |= 0x00000440; \/* data size byte, mem incr, mem-to-peripheral *\/\n    DMA1_Stream6-&gt;CR |= 0x16;       \/* enable interrupts DMA_IT_TC | DMA_IT_TE | DMA_IT_DME *\/\n    DMA1_Stream6-&gt;CR |= 1;          \/* enable DMA1 Stream 6 *\/\n}\n\n\nvoid DMA1_Stream6_IRQHandler(void)\n{\n    if (DMA1-&gt;HISR &amp; 0x000C0000)    \/* if an error occurred *\/\n        while(1) {}                 \/* substitute this by error handling *\/\n    DMA1-&gt;HIFCR = 0x003F0000;       \/* clear all interrupt flags of Stream 6 *\/\n    DMA1_Stream6-&gt;CR &amp;= ~0x10;      \/* disable DMA1 Stream 6 TCIE *\/\n}\n\n\nvoid USART2_IRQHandler(void)\n{\n    USART2-&gt;SR &amp;= ~0x0040;          \/* clear transmit complete interrupt flag *\/\n    done = 1;                       \/* set the done flag *\/\n}\n\nvoid DMA1_Stream5_IRQHandler(void)\n\t\t{\n\t\tif((DMA1-&gt;HISR)&amp;(1&lt;&lt;11)) \/\/DMA receive complete\n\t\t\t{\n\t\t\tdone_rec=1;\n\t\t\tDMA1-&gt;HIFCR|=(1&lt;&lt;11);\n\t\t\t}\n\t\t}<\/pre><\/div>\n\n\n\n<p>Demo<\/p>\n\n\n\n<figure class=\"wp-block-video\"><video controls src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Recording-2021-09-23-at-8.28.00-AM.mov\"><\/video><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>In pervious guides, we took look how to send string using DMA (here), and how to receive characters using interrupt(here). In this guide, we shall use DMA to receive 5 characters and echo back the received character using DMA also. In this guide, we will cover the following: Configure UART for full duplex (TX and [&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-442","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\/442"}],"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=442"}],"version-history":[{"count":2,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/442\/revisions"}],"predecessor-version":[{"id":450,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/442\/revisions\/450"}],"wp:attachment":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=442"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=442"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=442"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}