{"id":708,"date":"2022-01-17T04:35:44","date_gmt":"2022-01-17T04:35:44","guid":{"rendered":"https:\/\/blog.embeddedexpert.io\/?p=708"},"modified":"2022-01-17T04:35:47","modified_gmt":"2022-01-17T04:35:47","slug":"working-with-stm32-and-spi-full-duplex-mode-with-dma","status":"publish","type":"post","link":"https:\/\/blog.embeddedexpert.io\/?p=708","title":{"rendered":"Working with STM32 and SPI: Full Duplex Mode with 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 rel=\"noreferrer noopener\" href=\"https:\/\/blog.embeddedexpert.io\/?p=474\" data-type=\"URL\" data-id=\"https:\/\/blog.embeddedexpert.io\/?p=474\" target=\"_blank\">here<\/a>), we took a look at the SPI transmit mode using DMA. In this guide, we shall use DMA to send and receive data from slave device (MPU9250) in this case using only DMA.<\/p>\n\n\n\n<p>In the guide we will cover the following:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>SPI configuration for DMA<\/li><li>DMA cofinguration <\/li><li>SPI-TX and SPI-RX code<\/li><li>Connection <\/li><li>Code<\/li><li>Demo<\/li><\/ul>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">1. SPI configuration for DMA:<\/h2>\n\n\n\n<p><\/p>\n\n\n\n<p>From the previous guide (<em><a rel=\"noreferrer noopener\" href=\"https:\/\/blog.embeddedexpert.io\/?p=474\" data-type=\"URL\" data-id=\"https:\/\/blog.embeddedexpert.io\/?p=474\" target=\"_blank\">Working with STM32 and SPI : Send bytes using DMA<\/a><\/em>) we can grab the initialization function for the SPI clock, pins 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\t#define ch3\t\t(0x03&lt;&lt;25)\n\t\t#define AF05  (0x05)\n\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]|=(AF05&lt;&lt;20)|(AF05&lt;&lt;24)|(AF05&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|SPI_CR1_CPHA|SPI_CR1_CPOL;<\/pre><\/div>\n\n\n\n<p>From control register 2 (CR2) we can enable DMA for TX and RX as following:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"240\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-17-at-7.01.57-AM-1024x240.png\" alt=\"\" class=\"wp-image-709\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-17-at-7.01.57-AM-1024x240.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-17-at-7.01.57-AM-300x70.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-17-at-7.01.57-AM-768x180.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-17-at-7.01.57-AM-1536x360.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-17-at-7.01.57-AM-2048x480.png 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-17-at-7.01.57-AM-1150x269.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-17-at-7.01.57-AM-750x176.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-17-at-7.01.57-AM-400x94.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-17-at-7.01.57-AM-250x59.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\t\t\/\/enable DMA_TX DMA_RX buffer\n\t\tSPI1-&gt;CR2|=SPI_CR2_TXDMAEN|SPI_CR2_RXDMAEN;<\/pre><\/div>\n\n\n\n<p>And finally enable SPI<\/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\t\t\/\/enable SPI peripheral\n\t\tSPI1-&gt;CR1|=SPI_CR1_SPE;<\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">2. DMA configuration:<\/h2>\n\n\n\n<p><\/p>\n\n\n\n<p>Before we start configuring the DMA, we need to check which channel and stream for the SPI_TX and SPI_RX.<\/p>\n\n\n\n<p>From the DMA section table 28 in reference manual of STM32F411, we can find which stream and channel.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"529\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-17-at-7.04.30-AM-1024x529.png\" alt=\"\" class=\"wp-image-710\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-17-at-7.04.30-AM-1024x529.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-17-at-7.04.30-AM-300x155.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-17-at-7.04.30-AM-768x397.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-17-at-7.04.30-AM-1536x794.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-17-at-7.04.30-AM-2048x1058.png 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-17-at-7.04.30-AM-1150x594.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-17-at-7.04.30-AM-750x388.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-17-at-7.04.30-AM-400x207.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-17-at-7.04.30-AM-250x129.png 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Sine we have multiple streams and channel, we shall use Stream2 and Stream3 and the channel shall be 3.<\/p>\n\n\n\n<p>Hence we create symbolic name for channel3 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;}\">#define ch3\t\t(0x03&lt;&lt;25)<\/pre><\/div>\n\n\n\n<p>For SPI_TX we shall use DM2_Stream3<\/p>\n\n\n\n<p>For DMA configuration, we need to configure the DMA with the following paramters:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Channel: Channel 3.<\/li><li>Memory and Peripheral size to 8-bit.<\/li><li>Memory increment.<\/li><li>Direction: Memory to peripheral.<\/li><li>Enable transfer complete, half transfer transfer error and direct mode error interrupt and we don&#8217;t need to enable the Stream yet.<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"355\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-17-at-7.11.06-AM-1024x355.png\" alt=\"\" class=\"wp-image-711\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-17-at-7.11.06-AM-1024x355.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-17-at-7.11.06-AM-300x104.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-17-at-7.11.06-AM-768x266.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-17-at-7.11.06-AM-1536x533.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-17-at-7.11.06-AM-2048x710.png 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-17-at-7.11.06-AM-1150x399.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-17-at-7.11.06-AM-750x260.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-17-at-7.11.06-AM-400x139.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-17-at-7.11.06-AM-250x87.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\t\/\/SPI_TX\nvoid dma2_stream3_ch3_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\tDMA2_Stream3-&gt;FCR |= DMA_SxFCR_DMDIS;\n  DMA2_Stream3-&gt;FCR |= (DMA_SxFCR_FTH_0 | DMA_SxFCR_FTH_1);\n\t\n\tNVIC_EnableIRQ(DMA2_Stream3_IRQn);\n\t\n\t}<\/pre><\/div>\n\n\n\n<p>For SPI_RX we shall use Stream2 with the following configuration:<\/p>\n\n\n\n<p><li>Channel: Channel 3.<\/li><\/p>\n\n\n\n<p><li>Memory and Peripheral size to 8-bit.<\/li><\/p>\n\n\n\n<p><li>Memory increment.<\/li><\/p>\n\n\n\n<p><li>Direction: Peripheral to memory<\/li><\/p>\n\n\n\n<p><li>.Enable transfer complete, half transfer transfer error and direct mode error interrupt and we don&#8217;t need to enable the Stream yet.<\/li><\/p>\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;}\">\/\/SPI_RX\n\tvoid dma2_stream2_ch3_init(void)\n\t{\n\tRCC-&gt;AHB1ENR|=RCC_AHB1ENR_DMA2EN;\n\tDMA2_Stream2-&gt;CR&amp;=~DMA_SxCR_EN;\n\twhile((DMA2_Stream2-&gt;CR)&amp;DMA_SxCR_EN){;}\n\tDMA2_Stream2-&gt;CR=ch3|DMA_SxCR_MINC|DMA_SxCR_TCIE\n\t|DMA_SxCR_HTIE|DMA_SxCR_TEIE|DMA_SxCR_DMEIE;\n\tDMA2_Stream2-&gt;FCR |= DMA_SxFCR_DMDIS;\n  DMA2_Stream2-&gt;FCR |= (DMA_SxFCR_FTH_0 | DMA_SxFCR_FTH_1);\n\tNVIC_EnableIRQ(DMA2_Stream2_IRQn);\n\t\n\t}<\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">3. SPI_TX and SPI_RX code:<\/h2>\n\n\n\n<p>For transferring data, first declare a function that takes two arguments:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Source<\/li><li>Length<\/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 spi_transfer_dma(uint32_t src,uint32_t len){<\/pre><\/div>\n\n\n\n<p>Inside the function, first clear all pending flags:<\/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 be SPI-&gt;DR<\/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>Memory0 location to be the source (src):<\/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>Number of transfer to be 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;}\">DMA2_Stream3-&gt;NDTR=len;<\/pre><\/div>\n\n\n\n<p>Finally enable the stream<\/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;\n}<\/pre><\/div>\n\n\n\n<p>For SPI_RX, the code shall be:<\/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 spi_receive_dma (uint32_t dest,uint32_t len)\n\t\t\t\t{\n\t\t\t\tDMA2-&gt;LIFCR |=DMA_LIFCR_CTCIF2|DMA_LIFCR_CHTIF2|DMA_LIFCR_CTEIF2|DMA_LIFCR_CDMEIF2|DMA_LIFCR_CFEIF2;\n\t\t\t\t\n\t\t\t\tDMA2_Stream2-&gt;PAR= (uint32_t)&amp;(SPI1-&gt;DR);\n\t\t\t\tDMA2_Stream2-&gt;M0AR=dest;\n\t\t\t\tDMA2_Stream2-&gt;NDTR=len;\n\t\t\t\tDMA2_Stream2-&gt;CR|=DMA_SxCR_EN;\n\t\t\t\t}<\/pre><\/div>\n\n\n\n<p>Finally, Interrupt handling:<\/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 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\ttx_finished=1;\n\t\t\t\t\n\t\t\t\t\tDMA2_Stream3-&gt;CR&amp;=~DMA_SxCR_EN;\n\t\t\t\t\t\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\t\n\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\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\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\n\t\t\t\t\t\tDMA2-&gt;LIFCR|=(DMA_LIFCR_CFEIF0);\n\t\t\t\t\t\t}\n\t\t\tNVIC_ClearPendingIRQ(DMA2_Stream3_IRQn);\n\t\t\t\n\t\t}\n\t\t\n\t\t\nvoid DMA2_Stream2_IRQHandler(void)\n\t\t{\n\t\t\t\n\t\tif(DMA2-&gt;LISR&amp;(DMA_LISR_TCIF2))\n\t\t\t\t{\n\t\t\t\t\trx_finished=1;\n\n\t\t\t\t\tDMA2_Stream2-&gt;CR&amp;=~DMA_SxCR_EN;\n\n\t\t\t\t\tDMA2-&gt;LIFCR |=DMA_LIFCR_CTCIF2;\n\t\t\t\t}\n\t\t\t\t\n\t\tif(DMA2-&gt;LISR&amp;(DMA_LISR_HTIF2))\n\t\t\t\t{\n\t\t\t\t\t\n\n\t\t\t\t\tDMA2-&gt;LIFCR |=DMA_LIFCR_CHTIF2;\n\t\t\t\t}\n\t\t\t\t\n\t\t\n\t\tif(DMA2-&gt;LISR&amp;(DMA_LISR_TEIF2))\n\t\t\t\t\t\t{\n\n\t\t\t\t\t\tDMA2-&gt;LIFCR|=(DMA_LIFCR_CTEIF2);\n\t\t\t\t\t\t}\n\t\t\t\t\t\t\n\t\tif(DMA2-&gt;LISR&amp;(DMA_LISR_DMEIF2))\n\t\t\t\t\t\t{\n\n\t\t\t\t\t\tDMA2-&gt;LIFCR|=(DMA_LIFCR_CDMEIF2);\n\t\t\t\t\t\t}\n\t\t\t\t\t\t\n\t\tif(DMA2-&gt;LISR&amp;(DMA_LISR_FEIF2))\n\t\t\t\t\t\t{\n\n\t\t\t\t\t\tDMA2-&gt;LIFCR|=(DMA_LIFCR_CFEIF2);\n\t\t\t\t\t\t}\n\n\t\t\tNVIC_ClearPendingIRQ(DMA2_Stream2_IRQn);\n\t\t}\n<\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">4. Connection:<\/h2>\n\n\n\n<p>Required parts:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>STM32F411RE Nucleo<\/li><li>MPU9250 breakout <\/li><li>hookup wires<\/li><\/ul>\n\n\n\n<p>For the connection of MPU9250 in the SPI mode, the module breakout shall be connect as following:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"774\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-17-at-6.39.56-AM-1024x774.png\" alt=\"\" class=\"wp-image-712\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-17-at-6.39.56-AM-1024x774.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-17-at-6.39.56-AM-300x227.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-17-at-6.39.56-AM-768x581.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-17-at-6.39.56-AM-1536x1161.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-17-at-6.39.56-AM-2048x1548.png 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-17-at-6.39.56-AM-1150x869.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-17-at-6.39.56-AM-750x567.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-17-at-6.39.56-AM-400x302.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-17-at-6.39.56-AM-250x189.png 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">5. Code:<\/h2>\n\n\n\n<p>In order to read from MPU9250 we need to initialize it first 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;}\">uint8_t data[2];\ndouble accelRange,gyroRange;\n#define maximum_transfer 6\nstatic uint8_t dummy_buffer[maximum_transfer];\nchar accelBuf[maximum_transfer+1];\nvolatile uint8_t tx_finished,rx_finished;\n#define READ_FLAG   0x80\n\nvoid MPU9250_beginAccel(uint8_t mode) {\n  switch(mode) {\n  case ACC_FULL_SCALE_2_G:\n    accelRange = 2.0;\n    break;\n  case ACC_FULL_SCALE_4_G:\n    accelRange = 4.0;\n    break;\n  case ACC_FULL_SCALE_8_G:\n    accelRange = 8.0;\n    break;\n  case ACC_FULL_SCALE_16_G:\n    accelRange = 16.0;\n    break;\n  default:\n    return; \/\/ Return without writing invalid mode\n  }\n \t\n\tdata[0]=USER_CTRL; data[1]=(1&lt;&lt;4);\n\tspi_transfer_dma((uint32_t)data,2);\n\twhile(tx_finished==0){;}\n\t\ttx_finished=0;\n\t\t\n\tdata[0]=MPU9250_ADDR_ACCELCONFIG; data[1]=mode;\n\tspi_transfer_dma((uint32_t)data,2);\n\twhile(tx_finished==0){;}\n\t\ttx_finished=0;\n}\n<\/pre><\/div>\n\n\n\n<p>To update the values:<\/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;}\">\nuint8_t MPU9250_accelUpdate(void) {\n\tdummy_buffer[0]=0x3B|READ_FLAG;\n\t\n\tspi_receive_dma(accelBuf,7);\n\tspi_transfer_dma(dummy_buffer,7);\n\twhile(rx_finished==0){;}\n\trx_finished=0;\n\treturn 0;\n}<\/pre><\/div>\n\n\n\n<p>Notice first we need to set the DMA to receive data first before we can transmit the read request<\/p>\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\/01\/SPI_DMA.zip\">SPI_DMA<\/a><a href=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/SPI_DMA.zip\" class=\"wp-block-file__button\" download>Download<\/a><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">6. Demo:<\/h2>\n\n\n\n<p>After you compile and upload the code. Add acc_x,acc_y,acc_z to watch window you should get similar results to the video when rotation the MPU9250 (This is for the acceleration part only).<\/p>\n\n\n\n<figure class=\"wp-block-video\"><video controls src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Recording-2022-01-17-at-6.53.47-AM.mov\"><\/video><\/figure>\n\n\n\n<p>Happy coding \ud83d\ude42 <\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In the previous guide (here), we took a look at the SPI transmit mode using DMA. In this guide, we shall use DMA to send and receive data from slave device (MPU9250) in this case using only DMA. In the guide we will cover the following: SPI configuration for DMA DMA cofinguration SPI-TX and SPI-RX [&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-708","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\/708"}],"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=708"}],"version-history":[{"count":2,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/708\/revisions"}],"predecessor-version":[{"id":1118,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/708\/revisions\/1118"}],"wp:attachment":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=708"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=708"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=708"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}