{"id":474,"date":"2021-10-04T06:04:17","date_gmt":"2021-10-04T06:04:17","guid":{"rendered":"https:\/\/blog.embeddedexpert.io\/?p=474"},"modified":"2021-10-04T06:04:20","modified_gmt":"2021-10-04T06:04:20","slug":"working-with-stm32-and-spi-send-bytes-using-dma","status":"publish","type":"post","link":"https:\/\/blog.embeddedexpert.io\/?p=474","title":{"rendered":"Working with STM32 and SPI : Send bytes using DMA"},"content":{"rendered":"\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img decoding=\"async\" src=\"https:\/\/community.nxp.com\/t5\/image\/serverpage\/image-id\/1775i2B1DEDD6CA621B46\/image-size\/large?v=v2&amp;px=999\" alt=\"pastedImage_0.png\" title=\"pastedImage_0.png\" \/><\/figure><\/div>\n\n\n\n<p>In the previous guide (<a href=\"https:\/\/blog.embeddedexpert.io\/?p=466\" data-type=\"URL\" data-id=\"https:\/\/blog.embeddedexpert.io\/?p=466\" target=\"_blank\" rel=\"noreferrer noopener\">here<\/a>), we discussed how to send a single character using SPI in polling mode. This method will decrease the CPU performance since the CPU has to wait for each time before sending the character. In this guide, we shall introduce DMA to send number of byte without blocking the operation of the CPU.<\/p>\n\n\n\n<p>In this guide, we shall discuss the following:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Enable DMA in SPI<\/li><li>Initialize the DMA<\/li><li>Configure the DMA to send data<\/li><li>Results<\/li><\/ul>\n\n\n\n<p>Note: in this guide, we will use STM32F407VGT. For another type of F4 series, you need to check the stream and channel.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">1. Enable DMA for SPI:<\/h2>\n\n\n\n<p>The extra step needed to enable DMA_TX for SPI is to enable TXDMAEN bit in Control Register 2 (CR2)<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"266\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/10\/Screen-Shot-2021-10-04-at-8.33.55-AM-1024x266.png\" alt=\"\" class=\"wp-image-475\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/10\/Screen-Shot-2021-10-04-at-8.33.55-AM-1024x266.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/10\/Screen-Shot-2021-10-04-at-8.33.55-AM-300x78.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/10\/Screen-Shot-2021-10-04-at-8.33.55-AM-768x199.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/10\/Screen-Shot-2021-10-04-at-8.33.55-AM-1536x399.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/10\/Screen-Shot-2021-10-04-at-8.33.55-AM-2048x532.png 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/10\/Screen-Shot-2021-10-04-at-8.33.55-AM-1150x299.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/10\/Screen-Shot-2021-10-04-at-8.33.55-AM-750x195.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/10\/Screen-Shot-2021-10-04-at-8.33.55-AM-400x104.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/10\/Screen-Shot-2021-10-04-at-8.33.55-AM-250x65.png 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure><\/div>\n\n\n\n<p>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;}\">SPI1-&gt;CR2|=SPI_CR2_TXDMAEN;<\/pre><\/div>\n\n\n\n<p>Hence the initialization will be 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;}\">\/*\n\t* @brief initialize SPI1 peripheral and required pins\n  * @param  None\n  * @retval None\t\t\n\t\t\n*\/\nvoid spi1_init(void)\n\t\t{\n\t\t\t\/\/enable clock for GPIOA\n\t\tRCC-&gt;AHB1ENR|=RCC_AHB1ENR_GPIOAEN; \n\t\t\t\/\/set PA5, PA6 and PA7 to alternate function mode\n\t\tGPIOA-&gt;MODER|=GPIO_MODER_MODE5_1|GPIO_MODER_MODE6_1|GPIO_MODER_MODE7_1; \n\t\t\t\/\/set which type of alternate function is\n\t\tGPIOA-&gt;AFR[0]|=(0x05&lt;&lt;20)|(0x05&lt;&lt;24)|(0x05&lt;&lt;28);\n\t\t\t\/\/enable clock access to SPI1\n\t\tRCC-&gt;APB2ENR|=RCC_APB2ENR_SPI1EN;\n\t\t\t\/\/set software slave managment\n\t\tSPI1-&gt;CR1|=SPI_CR1_SSM|SPI_CR1_SSI;\n\t\t\t\/\/set SPI in master mode\n\t\tSPI1-&gt;CR1|=SPI_CR1_MSTR;\n\t\tSPI1-&gt;CR1|=SPI_CR1_BR_0;\n\t\t\t\/\/enable DMA_TX buffer\n\t\tSPI1-&gt;CR2|=SPI_CR2_TXDMAEN;\n\t\t\t\/\/enable SPI peripheral\n\t\tSPI1-&gt;CR1|=SPI_CR1_SPE;\n\t\t\n\t\t\n\t\t}<\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">2. 1 Initialize the DMA:<\/h2>\n\n\n\n<p>Before the Initializing, we need to know which Stream and Channel is Connected to SPI_TX<\/p>\n\n\n\n<p>According the figure below, we have two options, either Stream 5 or Stream 3 and both on Channel 3. <\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"504\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/10\/Screen-Shot-2021-10-04-at-8.37.23-AM-1024x504.png\" alt=\"\" class=\"wp-image-476\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/10\/Screen-Shot-2021-10-04-at-8.37.23-AM-1024x504.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/10\/Screen-Shot-2021-10-04-at-8.37.23-AM-300x148.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/10\/Screen-Shot-2021-10-04-at-8.37.23-AM-768x378.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/10\/Screen-Shot-2021-10-04-at-8.37.23-AM-1536x756.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/10\/Screen-Shot-2021-10-04-at-8.37.23-AM-2048x1008.png 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/10\/Screen-Shot-2021-10-04-at-8.37.23-AM-1150x566.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/10\/Screen-Shot-2021-10-04-at-8.37.23-AM-750x369.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/10\/Screen-Shot-2021-10-04-at-8.37.23-AM-400x197.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/10\/Screen-Shot-2021-10-04-at-8.37.23-AM-250x123.png 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>In our case, we shall use Stream 3.<\/p>\n\n\n\n<p>We start off by enabling clock access to DMA2 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_DMA2EN;<\/pre><\/div>\n\n\n\n<p>Then disable the stream and make sure it is disabled 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;}\">DMA2_Stream3-&gt;CR&amp;=~DMA_SxCR_EN;\n\twhile((DMA2_Stream3-&gt;CR)&amp;DMA_SxCR_EN){;}<\/pre><\/div>\n\n\n\n<p>Set DMA2_Stream3 to for channel 3, increment the Memory, set direction from memory to peripheral and enable the following interrupts:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Transfer Complete Interrupt<\/li><li>Half transfer interrupt<\/li><li>Transfer error interrupt<\/li><li>Direct Mode error interrupt<\/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;}\">#define ch3\t\t(0x03&lt;&lt;25)\nDMA2_Stream3-&gt;CR=ch3|DMA_SxCR_MINC|DMA_SxCR_DIR_0|DMA_SxCR_TCIE\n\t|DMA_SxCR_HTIE|DMA_SxCR_TEIE|DMA_SxCR_DMEIE;<\/pre><\/div>\n\n\n\n<p>Then we enable direct mode 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;}\">DMA2_Stream3-&gt;FCR&amp;=~DMA_SxFCR_DMDIS;<\/pre><\/div>\n\n\n\n<p>Finally enable the interrupt in NVIC 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;}\">NVIC_EnableIRQ(DMA2_Stream3_IRQn);<\/pre><\/div>\n\n\n\n<p>Hence the initialisation will be 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;}\">\/*\n\t* @brief intialize DMA2 Stream3 Channel 3\n  * @param  None\n  * @retval None\t\t\n\t\t\n*\/\nvoid dma2_stream3_ch2_init(void)\n\t{\n\tRCC-&gt;AHB1ENR|=RCC_AHB1ENR_DMA2EN;\n\tDMA2_Stream3-&gt;CR&amp;=~DMA_SxCR_EN;\n\twhile((DMA2_Stream3-&gt;CR)&amp;DMA_SxCR_EN){;}\n\tDMA2_Stream3-&gt;CR=ch3|DMA_SxCR_MINC|DMA_SxCR_DIR_0|DMA_SxCR_TCIE\n\t|DMA_SxCR_HTIE|DMA_SxCR_TEIE|DMA_SxCR_DMEIE;\n\t\/\/DMA2_Stream3-&gt;FCR=0;\n\tDMA2_Stream3-&gt;FCR&amp;=~DMA_SxFCR_DMDIS;\n\tNVIC_EnableIRQ(DMA2_Stream3_IRQn);\n\t\n\t}<\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">2.2 DMA transfer setup<\/h2>\n\n\n\n<p>We start of by clearing all pending interrupts 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;}\">DMA2-&gt;LIFCR |=DMA_LIFCR_CTCIF3|DMA_LIFCR_CHTIF3|DMA_LIFCR_CTEIF3|DMA_LIFCR_CDMEIF3|DMA_LIFCR_CFEIF3;<\/pre><\/div>\n\n\n\n<p>Then set the peripheral address to SPI-&gt;DR 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;}\">DMA2_Stream3-&gt;PAR= (uint32_t)&amp;SPI1-&gt;DR;<\/pre><\/div>\n\n\n\n<p>Set memory address to be the byte(s) to be sent 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;}\">DMA2_Stream3-&gt;M0AR=src;<\/pre><\/div>\n\n\n\n<p>Next we set how much data to be transferred 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;}\">DMA2_Stream3-&gt;NDTR=len;<\/pre><\/div>\n\n\n\n<p>Finally, we shall enable the 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;}\">DMA2_Stream3-&gt;CR|=DMA_SxCR_EN;<\/pre><\/div>\n\n\n\n<p>Hence, the SPI transfer function using DMA shall be something like this:<\/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\t* @brief initiation DMA transfer\n  * @param  uint32_t src for data source \n\t* @param  uint32_t length of data source \t\n  * @retval None\t\t\n\t\t\n*\/\n\t\n\tvoid spi_transfer_dma(uint32_t src,uint32_t len)\n\t\t\t{\n\t\t\t\tDMA2-&gt;LIFCR |=DMA_LIFCR_CTCIF3|DMA_LIFCR_CHTIF3|DMA_LIFCR_CTEIF3|DMA_LIFCR_CDMEIF3|DMA_LIFCR_CFEIF3;\n\t\t\t\tDMA2_Stream3-&gt;PAR= (uint32_t)&amp;SPI1-&gt;DR;\n\t\t\t\tDMA2_Stream3-&gt;M0AR=src;\n\t\t\t\tDMA2_Stream3-&gt;NDTR=len;\n\t\t\t\tDMA2_Stream3-&gt;CR|=DMA_SxCR_EN;\n\t\t\t\n\t\t\t}<\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">2.3 DMA interrupt handling<\/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;}\">void DMA2_Stream3_IRQHandler(void)\n\t\t{\n\t\t\t\n\t\tif(DMA2-&gt;LISR&amp;(DMA_LISR_TCIF3))\n\t\t\t\t{\n\t\t\t\t\tLED_PORT-&gt;ODR^=LED_blue;\n\t\t\t\t\tprintf(&quot;finished transfered\\r\\n&quot;);\n\t\t\t\t\tfinished=1; \n\t\t\t\t\tDMA2_Stream3-&gt;CR&amp;=~DMA_SxCR_EN;\n\t\t\t\t\tDMA2-&gt;LIFCR |=DMA_LIFCR_CTCIF3;\n\t\t\t\t}\n\t\t\t\t\n\t\tif(DMA2-&gt;LISR&amp;(DMA_LISR_HTIF3))\n\t\t\t\t{\n\t\t\t\t\tLED_PORT-&gt;ODR^=LED_green;\n\t\t\t\t\tprintf(&quot;half transfered\\r\\n&quot;);\n\t\t\t\t\tDMA2-&gt;LIFCR |=DMA_LIFCR_CHTIF3;\n\t\t\t\t}\n\t\t\t\t\n\t\t\n\t\tif(DMA2-&gt;LISR&amp;(DMA_LISR_TEIF3))\n\t\t\t\t\t\t{\n\t\t\t\t\t\tprintf(&quot;transfer error interrupt\\r\\n&quot;);\n\t\t\t\t\t\tDMA2-&gt;LIFCR|=(DMA_LIFCR_CTEIF3);\n\t\t\t\t\t\t}\n\t\t\t\t\t\t\n\t\tif(DMA2-&gt;LISR&amp;(DMA_LISR_DMEIF3))\n\t\t\t\t\t\t{\n\t\t\t\t\t\tprintf(&quot;Direct mode interrupt error\\r\\n&quot;);\n\t\t\t\t\t\tDMA2-&gt;LIFCR|=(DMA_LIFCR_CDMEIF3);\n\t\t\t\t\t\t}\n\t\t\t\t\t\t\n\t\tif(DMA2-&gt;LISR&amp;(DMA_LISR_FEIF3))\n\t\t\t\t\t\t{\n\t\t\t\t\t\tprintf(&quot;FIFO error interrupt\\r\\n&quot;);\n\t\t\t\t\t\tDMA2-&gt;LIFCR|=(DMA_LIFCR_CFEIF3);\n\t\t\t\t\t\t}\n\n\t\t\tNVIC_ClearPendingIRQ(DMA2_Stream3_IRQn);\n\t\t}<\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">2.4 Data to send<\/h2>\n\n\n\n<p>We will send the following characters:<\/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;}\">char data[]={'A','B','C','D','E','F','G'};<\/pre><\/div>\n\n\n\n<p>Which they should have the hex value from 0x41 to 0x47<\/p>\n\n\n\n<p>In order to send the data using DMA we will use spi_transfer_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;}\">spi_transfer_dma((uint32_t)data,sizeof(data));\n\t\t\twhile(finished==0){} \/\/wait untill data is transfered \n\t\t\tfinished=0;\n\t\t\tdelayMs(10);<\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">2.5 Code Download:<\/h2>\n\n\n\n<p>You can download the entire code from here which is based on keil uVison IDE<\/p>\n\n\n\n<p class=\"has-text-align-center\"><a href=\"https:\/\/github.com\/hussamaldean\/SPI_TX_DMA_STM32F407\" data-type=\"URL\" data-id=\"https:\/\/github.com\/hussamaldean\/SPI_TX_DMA_STM32F407\" target=\"_blank\" rel=\"noreferrer noopener\">SPI_TX_DMA_STM32F407<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">3. Results:<\/h2>\n\n\n\n<p>Using Logic Analyzer and connecting D0 to PA5 and D2 to PA7 you shall get the following:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"161\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/10\/Screen-Shot-2021-10-03-at-9.07.25-PM-1024x161.png\" alt=\"\" class=\"wp-image-477\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/10\/Screen-Shot-2021-10-03-at-9.07.25-PM-1024x161.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/10\/Screen-Shot-2021-10-03-at-9.07.25-PM-300x47.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/10\/Screen-Shot-2021-10-03-at-9.07.25-PM-768x121.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/10\/Screen-Shot-2021-10-03-at-9.07.25-PM-1536x242.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/10\/Screen-Shot-2021-10-03-at-9.07.25-PM-2048x322.png 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/10\/Screen-Shot-2021-10-03-at-9.07.25-PM-1150x181.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/10\/Screen-Shot-2021-10-03-at-9.07.25-PM-750x118.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/10\/Screen-Shot-2021-10-03-at-9.07.25-PM-400x63.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/10\/Screen-Shot-2021-10-03-at-9.07.25-PM-250x39.png 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>As you can see, we are getting the correct value 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In the previous guide (here), we discussed how to send a single character using SPI in polling mode. This method will decrease the CPU performance since the CPU has to wait for each time before sending the character. In this guide, we shall introduce DMA to send number of byte without blocking the operation of [&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-474","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\/474"}],"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=474"}],"version-history":[{"count":1,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/474\/revisions"}],"predecessor-version":[{"id":478,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/474\/revisions\/478"}],"wp:attachment":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=474"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=474"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=474"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}