{"id":1733,"date":"2023-05-04T05:08:31","date_gmt":"2023-05-04T05:08:31","guid":{"rendered":"https:\/\/blog.embeddedexpert.io\/?p=1733"},"modified":"2023-05-04T05:08:36","modified_gmt":"2023-05-04T05:08:36","slug":"getting-started-with-stm32l053-spi-tx-dma","status":"publish","type":"post","link":"https:\/\/blog.embeddedexpert.io\/?p=1733","title":{"rendered":"Getting started with STM32L053: SPI  TX DMA"},"content":{"rendered":"\n<p><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"683\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/AdobeStock_122425803-2-1024x683.jpeg\" alt=\"\" class=\"wp-image-1736\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/AdobeStock_122425803-2-1024x683.jpeg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/AdobeStock_122425803-2-300x200.jpeg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/AdobeStock_122425803-2-768x512.jpeg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/AdobeStock_122425803-2-1536x1024.jpeg 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/AdobeStock_122425803-2-2048x1365.jpeg 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/AdobeStock_122425803-2-1150x767.jpeg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/AdobeStock_122425803-2-750x500.jpeg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/AdobeStock_122425803-2-400x267.jpeg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/AdobeStock_122425803-2-250x167.jpeg 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>In the previous guide (<a href=\"https:\/\/blog.embeddedexpert.io\/?p=1065\" data-type=\"URL\" data-id=\"https:\/\/blog.embeddedexpert.io\/?p=1065\" target=\"_blank\" rel=\"noreferrer noopener\">here<\/a>), we saw how to transmit data over SPI using polling mode. In this guide, we shall use DMA to transmit data over SPI without CPU intervention.<\/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>Configure SPI in DMA TX mode.<\/li><li>Configure DMA.<\/li><li>SPI DMA transmit function.<\/li><li>Code.<\/li><li>Results.<\/li><\/ul>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">1. Configure SPI in DMA TX mode:<\/h2>\n\n\n\n<p>Continue from the previous guide:<\/p>\n\n\n\n<p>In spi.h heaer file, declare the following enum:<\/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\tTx_Done=1,\n\tTX_Inprogress=0\n\n}SPI_TXStatus;<\/pre><\/div>\n\n\n\n<p>Then declare the following three new 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 spi_dma_init();\nvoid spi1_tx_dma(uint8_t * data, uint16_t len);\nuint8_t tx_status();<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>Hence, the entire header file as following:<\/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;}\">#ifndef SPI_H_\n#define SPI_H_\n\n#include &quot;stdint.h&quot;\n\n\ntypedef enum\n{\n\tTx_Done=1,\n\tTX_Inprogress=0\n\n}SPI_TXStatus;\n\nvoid spi_init();\nvoid spi_transmit(uint8_t *data,uint32_t size);\n\nvoid spi_dma_init();\nvoid spi1_tx_dma(uint8_t * data, uint16_t len);\nuint8_t tx_status();\n\n\nvoid cs_low();\nvoid cs_high();\n#endif \/* SPI_H_ *\/<\/pre><\/div>\n\n\n\n<p>in the source file named spi.c create new 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 spi_dma_init()<\/pre><\/div>\n\n\n\n<p>Within the 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;}\">\t\/*Enable clock access to GPIOA*\/\n\tRCC-&gt;IOPENR|=RCC_IOPENR_GPIOAEN;\n\n\n\t\/*Set PA0 to output and PA5 to PA7 alternate mode*\/\n\tGPIOA-&gt;MODER|=GPIO_MODER_MODE0_0|GPIO_MODER_MODE5_1|GPIO_MODER_MODE6_1|GPIO_MODER_MODE7_1;\n\n\tGPIOA-&gt;MODER&amp;=~(GPIO_MODER_MODE0_1|GPIO_MODER_MODE5_0|GPIO_MODER_MODE6_0|GPIO_MODER_MODE7_0);\n\n\t\/*Set speed to to very high speed*\/\n\n\tGPIOA-&gt;OSPEEDR|=(GPIO_OSPEEDER_OSPEED5)|(GPIO_OSPEEDER_OSPEED6)|(GPIO_OSPEEDER_OSPEED7);\n\n\t\/*Set GPIOs (PA5-PA7) to AF0*\/\n\n\tGPIOA-&gt;AFR[0]&amp;=~(GPIO_AFRL_AFSEL5_Msk&lt;&lt;GPIO_AFRL_AFSEL5_Pos|\n\t\t\tGPIO_AFRL_AFSEL6_Msk&lt;&lt;GPIO_AFRL_AFSEL6_Pos|\n\t\t\tGPIO_AFRL_AFSEL7_Msk&lt;&lt;GPIO_AFRL_AFSEL7_Pos);\n\n\t\/*Enable clock access to SPI1*\/\n\tRCC-&gt;APB2ENR|=RCC_APB2ENR_SPI1EN;\n\n\t\/*Set SPI to following parameters\n\t *\n\t * Software slave management\n\t * SPI to be master mode\n\t * Enable DMA_TX\n\t * Enable SPI module\n\t * *\/\n\n\t\/*Set to master, software slave management *\/\n\tSPI1-&gt;CR1|=SPI_CR1_MSTR|SPI_CR1_SSM|SPI_CR1_SSI;\n<\/pre><\/div>\n\n\n\n<p>This is similar to the previous guide until enabling the peripheral.<\/p>\n\n\n\n<p>Before enabling the peripheral, we shall enable the DMATX in CR2 of SPI:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"239\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-04-at-7.42.00-AM-1024x239.png\" alt=\"\" class=\"wp-image-1737\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-04-at-7.42.00-AM-1024x239.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-04-at-7.42.00-AM-300x70.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-04-at-7.42.00-AM-768x179.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-04-at-7.42.00-AM-1536x358.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-04-at-7.42.00-AM-2048x478.png 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-04-at-7.42.00-AM-1150x268.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-04-at-7.42.00-AM-750x175.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-04-at-7.42.00-AM-400x93.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-04-at-7.42.00-AM-250x58.png 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p><\/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;C&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">\t\/*Enable DMATX*\/\n\tSPI1-&gt;CR2|=SPI_CR2_TXDMAEN;<\/pre><\/div>\n\n\n\n<p>Finally, enable the SPI peripheral:<\/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\/*Enable SPI moduel*\/\n\tSPI1-&gt;CR1|=SPI_CR1_SPE;<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>Thats all for SPI. Next, DMA Configuration:<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">2. DMA Configuration:<\/h2>\n\n\n\n<p>First, enable clock access to DMA.<\/p>\n\n\n\n<p>Since STM32L053 has only single DMA and it is connected to AHB Bus, we can enable clock access to DMA1 as following:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"642\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screen-Shot-2022-08-17-at-7.26.00-AM-2048x1284-1-1024x642.png\" alt=\"\" class=\"wp-image-1738\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screen-Shot-2022-08-17-at-7.26.00-AM-2048x1284-1-1024x642.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screen-Shot-2022-08-17-at-7.26.00-AM-2048x1284-1-300x188.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screen-Shot-2022-08-17-at-7.26.00-AM-2048x1284-1-768x482.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screen-Shot-2022-08-17-at-7.26.00-AM-2048x1284-1-1536x963.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screen-Shot-2022-08-17-at-7.26.00-AM-2048x1284-1-1150x721.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screen-Shot-2022-08-17-at-7.26.00-AM-2048x1284-1-750x470.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screen-Shot-2022-08-17-at-7.26.00-AM-2048x1284-1-400x251.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screen-Shot-2022-08-17-at-7.26.00-AM-2048x1284-1-250x157.png 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screen-Shot-2022-08-17-at-7.26.00-AM-2048x1284-1.png 2048w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">\t\/*Enable clock access to DMA1*\/\n\tRCC-&gt;AHBENR|=RCC_AHBENR_DMA1EN;<\/pre><\/div>\n\n\n\n<p>Now, we need to know which channel and channel selection.<\/p>\n\n\n\n<p>The map request can be found in the reference manual DMA section:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"400\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-04-at-7.51.02-AM-1024x400.png\" alt=\"\" class=\"wp-image-1739\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-04-at-7.51.02-AM-1024x400.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-04-at-7.51.02-AM-300x117.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-04-at-7.51.02-AM-768x300.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-04-at-7.51.02-AM-1536x599.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-04-at-7.51.02-AM-2048x799.png 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-04-at-7.51.02-AM-1150x449.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-04-at-7.51.02-AM-750x293.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-04-at-7.51.02-AM-400x156.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-04-at-7.51.02-AM-250x98.png 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>From the request map, the channel 3 and channel selection is 1.<\/p>\n\n\n\n<p>The DMA shall be configured with the following parameters:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Direct Read from memory.<\/li><li>Memory increment mode.<\/li><li>Transfer complete interrupt.<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"406\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/08\/Screen-Shot-2022-08-29-at-4.24.13-PM-1024x406.png\" alt=\"\" class=\"wp-image-1178\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/08\/Screen-Shot-2022-08-29-at-4.24.13-PM-1024x406.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/08\/Screen-Shot-2022-08-29-at-4.24.13-PM-300x119.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/08\/Screen-Shot-2022-08-29-at-4.24.13-PM-768x305.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/08\/Screen-Shot-2022-08-29-at-4.24.13-PM-1536x610.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/08\/Screen-Shot-2022-08-29-at-4.24.13-PM-2048x813.png 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/08\/Screen-Shot-2022-08-29-at-4.24.13-PM-1150x455.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/08\/Screen-Shot-2022-08-29-at-4.24.13-PM-750x298.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/08\/Screen-Shot-2022-08-29-at-4.24.13-PM-400x159.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/08\/Screen-Shot-2022-08-29-at-4.24.13-PM-250x99.png 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">\t\/*Configure DMA with following parameters\n\t * Memory increment mode\n\t * Direction: Read from Memory\n\t * Transfer complete interrupt\n\t * *\/\n\tDMA1_Channel3-&gt;CCR|=DMA_CCR_MINC|DMA_CCR_DIR|DMA_CCR_TCIE;<\/pre><\/div>\n\n\n\n<p>Enable the interrupt in NVIC:<\/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\/*Enable the interrupt in NVIC*\/\n\tNVIC_EnableIRQ(DMA1_Channel2_3_IRQn);<\/pre><\/div>\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_Channel3-&gt;CPAR =(uint32_t)&amp;SPI1-&gt;DR;<\/pre><\/div>\n\n\n\n<p>Set channel 3 selection to be 1:<\/p>\n\n\n\n<p>Since this register doesn&#8217;t exist in the header, we shall create it 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 DMA_CSELR  (*(volatile unsigned int *)(0x400200a8))<\/pre><\/div>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"400\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-04-at-7.58.13-AM-1024x400.png\" alt=\"\" class=\"wp-image-1740\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-04-at-7.58.13-AM-1024x400.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-04-at-7.58.13-AM-300x117.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-04-at-7.58.13-AM-768x300.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-04-at-7.58.13-AM-1536x599.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-04-at-7.58.13-AM-2048x799.png 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-04-at-7.58.13-AM-1150x449.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-04-at-7.58.13-AM-750x293.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-04-at-7.58.13-AM-400x156.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-04-at-7.58.13-AM-250x98.png 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">\t\/*Set the channel selection*\/\n\tDMA_CSELR|=(0x01&lt;&lt;8);<\/pre><\/div>\n\n\n\n<p>Thats all for the spi_dma_init function.<\/p>\n\n\n\n<p>For 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_Channel2_3_IRQHandler()\n{\n\n\tif(DMA1-&gt;ISR &amp; DMA_ISR_TCIF3)\n\t{\n\t\t\/*Set tx_done to 1*\/\n\t\ttx_done=1;\n\t\t\/*Clear Interrupt flag*\/\n\t\tDMA1-&gt;IFCR =DMA_IFCR_CTCIF3;\n\n\t\t\/*Disable DMA*\/\n\t\tDMA1_Channel3-&gt;CCR&amp;=~DMA_CCR_EN;\n\n\t}\n\n}\n<\/pre><\/div>\n\n\n\n<p>Check if the source is transfer complete from channel 3, if it is:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Set tx_done to 1.<\/li><li>Clear the pending interrupt flag.<\/li><li>Disable the DMA channel.<\/li><\/ul>\n\n\n\n<p><\/p>\n\n\n\n<p>Check the status:<\/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 tx_status()\n{\n\tif(tx_done==0){return TX_Inprogress;}\n\telse {return Tx_Done;}\n}<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">3. SPI DMA transfer function:<\/h2>\n\n\n\n<p>The following are the steps required to transfer data over spi:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Reset tx_done flag.<\/li><li>Set the memory address to be the array passed as argument.<\/li><li>Set number of transfer.<\/li><li>Clear the interrupt flag.<\/li><li>Launch the DMA.<\/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 spi1_tx_dma(uint8_t * data, uint16_t len)\n{\n\t\/*Reset Tx flag*\/\n\ttx_done=0;\n\n\t\/*Set the memory address to be data*\/\n\tDMA1_Channel3-&gt;CMAR=(uint32_t)&amp;data[0];\n\n\t\/*Set the length*\/\n\tDMA1_Channel3-&gt;CNDTR=len;\n\n\t\/*Clear Interrupt flag*\/\n\tDMA1-&gt;IFCR =DMA_IFCR_CTCIF3;\n\n\tDMA1_Channel3-&gt;CCR|=DMA_CCR_EN;\n\n}<\/pre><\/div>\n\n\n\n<p>That all for TX function.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>In 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;\nuint8_t data[5]={0x01,0x02,0x03,0x04,0x05};\n\nint main(void)\n{\n\n\tspi_dma_init();\n\n\twhile(1)\n\t\t{\n\t\t\tcs_low();\n\t\t\tspi1_tx_dma(data,5);\n\t\t\twhile(tx_status()==TX_Inprogress);\n\t\t\tcs_high();\n\t\t\t\/*Delay a little bit*\/\n\t\t\tfor (int i=0;i&lt;10000;i++);\n\n\t\t}\n\n}<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">4. Code:<\/h2>\n\n\n\n<p>You may download the source 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_TX_DMA.zip\">SPI_TX_DMA<\/a><a href=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/05\/SPI_TX_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\">5. Results:<\/h2>\n\n\n\n<p><\/p>\n\n\n\n<p>When you connect logic analyzer to PA5, PA7 and PA0, you will get the following results:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"156\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/07\/Screen-Shot-2022-07-02-at-4.36.43-PM-1024x156.png\" alt=\"\" class=\"wp-image-1069\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/07\/Screen-Shot-2022-07-02-at-4.36.43-PM-1024x156.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/07\/Screen-Shot-2022-07-02-at-4.36.43-PM-300x46.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/07\/Screen-Shot-2022-07-02-at-4.36.43-PM-768x117.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/07\/Screen-Shot-2022-07-02-at-4.36.43-PM-1536x234.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/07\/Screen-Shot-2022-07-02-at-4.36.43-PM-2048x311.png 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/07\/Screen-Shot-2022-07-02-at-4.36.43-PM-1150x175.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/07\/Screen-Shot-2022-07-02-at-4.36.43-PM-750x114.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/07\/Screen-Shot-2022-07-02-at-4.36.43-PM-400x61.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/07\/Screen-Shot-2022-07-02-at-4.36.43-PM-250x38.png 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Happy coding \ud83d\ude42<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In the previous guide (here), we saw how to transmit data over SPI using polling mode. In this guide, we shall use DMA to transmit data over SPI without CPU intervention. In this guide, we shall cover the following: Configure SPI in DMA TX mode. Configure DMA. SPI DMA transmit function. Code. Results. 1. Configure [&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-1733","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\/1733"}],"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=1733"}],"version-history":[{"count":2,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/1733\/revisions"}],"predecessor-version":[{"id":1742,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/1733\/revisions\/1742"}],"wp:attachment":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1733"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1733"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1733"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}