{"id":1771,"date":"2023-05-20T14:54:17","date_gmt":"2023-05-20T14:54:17","guid":{"rendered":"https:\/\/blog.embeddedexpert.io\/?p=1771"},"modified":"2023-05-20T14:54:21","modified_gmt":"2023-05-20T14:54:21","slug":"getting-started-with-stm32l053-spi-full-duplex-using-dma","status":"publish","type":"post","link":"https:\/\/blog.embeddedexpert.io\/?p=1771","title":{"rendered":"Getting started with STM32L053: SPI Full Duplex using DMA"},"content":{"rendered":"\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/AdobeStock_122425803-2-1-2048x1365.jpeg\" alt=\"\" \/><\/figure>\n\n\n\n<p>In the previous guide (<a rel=\"noreferrer noopener\" href=\"https:\/\/blog.embeddedexpert.io\/?p=1743\" target=\"_blank\">here<\/a>), we tool a look for SPI in duplex mode using polling mode. In this guide, we shall see how to do SPI Full duplex 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>Enable RXDMA for SPI.<\/li><li>Configure DMA.<\/li><li>SPI RX with DMA<\/li><li>MPU9250 connection with STM32 and code modifucation.<\/li><li>Code.<\/li><li>Results.<\/li><\/ul>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">1. Enable RXDMA for SPI:<\/h2>\n\n\n\n<p>Before enabling the RXDMA for SPI. we need to add this enum to spi.h 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;}\">typedef enum\n{\n\tRx_Done=1,\n\tRX_Inprogress=0\n\n}SPI_RXStatus;<\/pre><\/div>\n\n\n\n<p>Also, add these 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;}\">void spi1_rx_dma(uint8_t * data, uint16_t len);\nuint8_t rx_status();<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>Within source file spi.c, add the following volatile variable:<\/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;}\">volatile uint8_t rx_done;<\/pre><\/div>\n\n\n\n<p>We start off by SPI TX DMA guide from <a href=\"https:\/\/blog.embeddedexpert.io\/?p=1733\" data-type=\"URL\" data-id=\"https:\/\/blog.embeddedexpert.io\/?p=1733\" target=\"_blank\" rel=\"noreferrer noopener\">here<\/a>.<\/p>\n\n\n\n<p>To enable RX in DMA for SPI, simply enable RXDMA from SPI1_CR2 register as following:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"263\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-20-at-5.26.17-PM-1024x263.png\" alt=\"\" class=\"wp-image-1772\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-20-at-5.26.17-PM-1024x263.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-20-at-5.26.17-PM-300x77.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-20-at-5.26.17-PM-768x197.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-20-at-5.26.17-PM-1536x394.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-20-at-5.26.17-PM-2048x526.png 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-20-at-5.26.17-PM-1150x295.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-20-at-5.26.17-PM-750x193.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-20-at-5.26.17-PM-400x103.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-20-at-5.26.17-PM-250x64.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;}\">\t\/*Enable DMARX*\/\n\tSPI1-&gt;CR2|=SPI_CR2_RXDMAEN;<\/pre><\/div>\n\n\n\n<p>The reset similar for SPI TX in DMA.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">2. Configure DMA:<\/h2>\n\n\n\n<p>Before configuring DMA for SPI RX, we need to find which channel responsible for SPI_RX.<\/p>\n\n\n\n<p>From DMA requests for each channel, we can find that SPI_RX is Channel2:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"386\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-20-at-5.30.21-PM-1024x386.png\" alt=\"\" class=\"wp-image-1773\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-20-at-5.30.21-PM-1024x386.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-20-at-5.30.21-PM-300x113.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-20-at-5.30.21-PM-768x289.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-20-at-5.30.21-PM-1536x578.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-20-at-5.30.21-PM-2048x771.png 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-20-at-5.30.21-PM-1150x433.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-20-at-5.30.21-PM-750x282.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-20-at-5.30.21-PM-400x151.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-20-at-5.30.21-PM-250x94.png 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Hence, we shall configure the channel with the following parameter:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Memory increment mode.<\/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=\"471\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-20-at-5.33.08-PM-1024x471.png\" alt=\"\" class=\"wp-image-1774\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-20-at-5.33.08-PM-1024x471.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-20-at-5.33.08-PM-300x138.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-20-at-5.33.08-PM-768x353.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-20-at-5.33.08-PM-1536x707.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-20-at-5.33.08-PM-2048x942.png 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-20-at-5.33.08-PM-1150x529.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-20-at-5.33.08-PM-750x345.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-20-at-5.33.08-PM-400x184.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-20-at-5.33.08-PM-250x115.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;}\">\n\t\/*DMA1 Channel 2 for SPI_RX*\/\n\n\n\tDMA1_Channel2-&gt;CCR|=DMA_CCR_MINC|DMA_CCR_TCIE;<\/pre><\/div>\n\n\n\n<p>The interrupt is already enabled in NVIC from the TX part since they both share same interrupt handler<\/p>\n\n\n\n<p>Set the peripheral address to be SPI1-&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;}\">\t\/*Set the peripheral address*\/\n\tDMA1_Channel2-&gt;CPAR =(uint32_t)&amp;SPI1-&gt;DR;<\/pre><\/div>\n\n\n\n<p>Set the channel to be 1 for SPI1 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\/*Set the channel selection*\/\n\tDMA_CSELR|=(0x01&lt;&lt;4);<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>For the interrupt handler, add the following if statement to the 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;}\">if(DMA1-&gt;ISR &amp; DMA_ISR_TCIF2)\n\t{\n\t\t\/*Set tx_done to 1*\/\n\t\trx_done=1;\n\n\t\t\/*Clear Interrupt flag*\/\n\t\tDMA1-&gt;IFCR =DMA_IFCR_CTCIF2;\n\n\t\t\/*Disable the stream*\/\n\t\tDMA1_Channel2-&gt;CCR&amp;=~DMA_CCR_EN;\n\n\t}<\/pre><\/div>\n\n\n\n<p>That all for DMA configuration.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">3. SPI RX in DMA:<\/h2>\n\n\n\n<p>To receive data from SPI bus, declare the following 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 spi1_rx_dma(uint8_t * data, uint16_t len)<\/pre><\/div>\n\n\n\n<p>The function takes two arguments:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Pointer to data to be read.<\/li><li>Length of the data to be received.<\/li><\/ul>\n\n\n\n<p>Within the function:<\/p>\n\n\n\n<p>Reset the rx_done flag:<\/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\/*Reset rx flag*\/\n\trx_done=0;<\/pre><\/div>\n\n\n\n<p>Set the memory address to be the pointer passed by the user:<\/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\/*Set the memory address to be data*\/\n\tDMA1_Channel2-&gt;CMAR=(uint32_t)&amp;data[0];<\/pre><\/div>\n\n\n\n<p>Set the length to the length passed by the user:<\/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\/*Set the length*\/\n\tDMA1_Channel2-&gt;CNDTR=len;<\/pre><\/div>\n\n\n\n<p>Clear the flag:<\/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\/*Clear Interrupt flag*\/\n\tDMA1-&gt;IFCR =DMA_IFCR_CTCIF2;<\/pre><\/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;}\">\t\/*Launch the DMA transfer*\/\n\tDMA1_Channel2-&gt;CCR|=DMA_CCR_EN;<\/pre><\/div>\n\n\n\n<p>Thats all for SPI_RX_DMA.<\/p>\n\n\n\n<p>To check if the received stream is finished:<\/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;}\">uint8_t rx_status()\n{\n\tif(rx_done==0){return RX_Inprogress;}\n\telse {return Rx_Done;}\n}<\/pre><\/div>\n\n\n\n<p>Thats all for the SPI in DMA mode.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">4.MPU9250 connection with STM32 and code modification:<\/h2>\n\n\n\n<p>The connection as following:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"774\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screen-Shot-2022-01-17-at-6.39.56-AM-2048x1548-1-1024x774.png\" alt=\"\" class=\"wp-image-1746\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screen-Shot-2022-01-17-at-6.39.56-AM-2048x1548-1-1024x774.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screen-Shot-2022-01-17-at-6.39.56-AM-2048x1548-1-300x227.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screen-Shot-2022-01-17-at-6.39.56-AM-2048x1548-1-768x581.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screen-Shot-2022-01-17-at-6.39.56-AM-2048x1548-1-1536x1161.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screen-Shot-2022-01-17-at-6.39.56-AM-2048x1548-1-1150x869.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screen-Shot-2022-01-17-at-6.39.56-AM-2048x1548-1-750x567.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screen-Shot-2022-01-17-at-6.39.56-AM-2048x1548-1-400x302.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screen-Shot-2022-01-17-at-6.39.56-AM-2048x1548-1-250x189.png 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screen-Shot-2022-01-17-at-6.39.56-AM-2048x1548-1.png 2048w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><figcaption>To read the data from MPU9250 acceleration part, the code as following:<\/figcaption><\/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;}\">uint8_t MPU9250_accelUpdate(void)\n{\n\tuint8_t data[6]={0x3B|READ_FLAG,0xFF,0xFF,0xFF,0xFF,0xFF};\n\tcs_low();\n\tspi1_rx_dma(accelBuf, 6);\n\tspi1_tx_dma(&amp;data, 6);\n\twhile(rx_status()==RX_Inprogress);\n\tcs_high();\n\treturn 0;\n \n}<\/pre><\/div>\n\n\n\n<p>Declare a buffer which will hold 6 bytes where first byte is the address to be read with read flag and 5 bytes of dummy data to keep the clock generated.<\/p>\n\n\n\n<p>Set the cs pin to low.<\/p>\n\n\n\n<p>start SPI_RX_DMA.<\/p>\n\n\n\n<p>transfer the address to be send with dummy data.<\/p>\n\n\n\n<p>wait until rx finished transfer.<\/p>\n\n\n\n<p>Set CS to high.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Same thing goes to gyroscope:<\/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;}\">uint8_t MPU9250_gyroUpdate(void)\n{\n\tuint8_t data[6]={0x43|READ_FLAG,0xFF,0xFF,0xFF,0xFF,0xFF};\n\tcs_low();\n\tspi1_rx_dma(gyroBuf,6);\n\tspi1_tx_dma(&amp;data, 6);\n\twhile(rx_status()==RX_Inprogress);\n\tcs_high();\n\treturn 0;\n}<\/pre><\/div>\n\n\n\n<p>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;spi.h&quot;\n#include &quot;MPU9250.h&quot;\n#include &quot;delay.h&quot;\n#include &quot;stdio.h&quot;\n#include &quot;uart.h&quot;\n\n\nint main(void)\n{\n\tuart_init();\n\tsystick_init_ms(2097000);\n\tspi_dma_init();\n\tMPU9250_beginAccel(ACC_FULL_SCALE_16_G);\n\tMPU9250_beginGyro(GYRO_FULL_SCALE_2000_DPS);\n\tprintf(&quot;hello from STM32L053\\r\\n&quot;);\n\twhile(1)\n\t\t{\n\t\t\tMPU9250_accelUpdate();\n\t\t\tMPU9250_gyroUpdate();\n\t\t\tprintf(&quot;---------------------------------------------\\r\\n&quot;);\n\t\t\tprintf(&quot;Acceleration data %0.3f %0.3f %0.3f \\r\\n&quot;,MPU9250_accelX(),MPU9250_accelY(),MPU9250_accelZ());\n\t\t\tprintf(&quot;Gyroscope data %0.3f %0.3f %0.3f \\r\\n&quot;,MPU9250_gyroX(),MPU9250_gyroY(),MPU9250_gyroZ());\n\t\t\tprintf(&quot;---------------------------------------------\\r\\n&quot;);\n\t\t\tdelay(500);\n\n\t\t}\n\n}\n\n<\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">5. Code:<\/h2>\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\/2023\/05\/SPI_FullDuplex_DMA.zip\">SPI_FullDuplex_DMA<\/a><a href=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/SPI_FullDuplex_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\">6. Results:<\/h2>\n\n\n\n<p><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"705\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-20-at-5.53.10-PM-1024x705.png\" alt=\"\" class=\"wp-image-1776\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-20-at-5.53.10-PM-1024x705.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-20-at-5.53.10-PM-300x206.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-20-at-5.53.10-PM-768x529.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-20-at-5.53.10-PM-1150x791.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-20-at-5.53.10-PM-750x516.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-20-at-5.53.10-PM-400x275.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-20-at-5.53.10-PM-250x172.png 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-20-at-5.53.10-PM.png 1174w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In the previous guide (here), we tool a look for SPI in duplex mode using polling mode. In this guide, we shall see how to do SPI Full duplex using DMA. In this guide, we shall cover the following: Enable RXDMA for SPI. Configure DMA. SPI RX with DMA MPU9250 connection with STM32 and code [&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-1771","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\/1771"}],"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=1771"}],"version-history":[{"count":1,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/1771\/revisions"}],"predecessor-version":[{"id":1777,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/1771\/revisions\/1777"}],"wp:attachment":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1771"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1771"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1771"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}