{"id":1923,"date":"2023-08-05T14:33:27","date_gmt":"2023-08-05T14:33:27","guid":{"rendered":"https:\/\/blog.embeddedexpert.io\/?p=1923"},"modified":"2023-08-05T14:33:29","modified_gmt":"2023-08-05T14:33:29","slug":"building-board-support-package-bsp-for-stm32f411-nucleo64-part12-spi-full-duplex","status":"publish","type":"post","link":"https:\/\/blog.embeddedexpert.io\/?p=1923","title":{"rendered":"Building Board Support Package (BSP) for STM32F411-Nucleo64 Part12: SPI Full Duplex"},"content":{"rendered":"\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\/08\/AdobeStock_128586024-1-1024x683.jpeg\" alt=\"\" class=\"wp-image-1924\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/08\/AdobeStock_128586024-1-1024x683.jpeg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/08\/AdobeStock_128586024-1-300x200.jpeg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/08\/AdobeStock_128586024-1-768x512.jpeg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/08\/AdobeStock_128586024-1-1536x1024.jpeg 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/08\/AdobeStock_128586024-1-2048x1365.jpeg 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/08\/AdobeStock_128586024-1-1150x767.jpeg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/08\/AdobeStock_128586024-1-750x500.jpeg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/08\/AdobeStock_128586024-1-400x267.jpeg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/08\/AdobeStock_128586024-1-250x167.jpeg 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>In this twelfth part of Board Support Package, we shall develop the receiver part of SPI to achieve full duplex communication with slave device which is in this case, MPU9250 sensor.<\/p>\n\n\n\n<p>In this guide, we shall cover the following:<\/p>\n\n\n\n<p><\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Modification of header file.<\/li><li>Modification of source file.<\/li><li>Main code.<\/li><li>Results.<\/li><\/ul>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">1. Modification of Header File:<\/h2>\n\n\n\n<p>Starting from the previous guide <a href=\"https:\/\/blog.embeddedexpert.io\/?p=1919\" data-type=\"URL\" data-id=\"https:\/\/blog.embeddedexpert.io\/?p=1919\" target=\"_blank\" rel=\"noreferrer noopener\">here<\/a>.<\/p>\n\n\n\n<p>We shall add the following function to end of the header file spi_bsp.h <\/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_StatusTypedef BSP_SPI_Receive(SPI_TypeDef *spi ,uint8_t *data,uint32_t size, uint32_t timeout);<\/pre><\/div>\n\n\n\n<p>The function takes four argument as following:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>SPI type def to determine which SPI to be used.<\/li><li>Pointer to data buffer to be read.<\/li><li>Size of the buffer.<\/li><li>Timeout for timeout management.<\/li><\/ul>\n\n\n\n<p>Hence, the entire 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;}\">#ifndef SPI_BSP_H_\n#define SPI_BSP_H_\n\n#include &quot;stdint.h&quot;\n#include &quot;stm32f4xx.h&quot;\n\n\n\ntypedef enum\n{\n\tspi1=0,\n\tspi2=1,\n\tspi3=2,\n\tspi4=3,\n\tspi5=4\n}SPI_EnableTypedef;\n\n\ntypedef enum\n{\n\tSPI_Succuss=0,\n\tSPI_Timeout=1,\n\n}SPI_StatusTypedef;\n\ntypedef enum\n{\n\teight_bit=0,\n\tsixteen_bit=1,\n\n\tsoftware_slave=1,\n\thardware_slave=0,\n\n\tLSB_First=1,\n\tMSB_First=0,\n\n\tFCLK_2=0,\n\tFCLK_4=1,\n\tFCLK_8=2,\n\tFCLK_16=3,\n\tFCLK_32=4,\n\tFCLK_64=5,\n\tFCLK_128=6,\n\tFCLK_256=7,\n\n\tMaster_mode=1,\n\tSlave_mode=0,\n\n\tCPOL0=0,\n\tCPOL1=1,\n\n\tCPHA0=0,\n\tCPHA1=1,\n\n}SPI_ConfigurationTypedef;\n\n\ntypedef struct\n{\n\tuint8_t mode;\n\tuint8_t dataFromat;\n\tuint8_t slaveManagement;\n\tuint8_t LSBFirst;\n\tuint8_t baud;\n\tuint8_t CPOL;\n\tuint8_t CPHA;\n}SPI_ConfigTypedef;\n\n\nvoid SPI_Enable_Clock(SPI_EnableTypedef spi_number);\n\nvoid BSP_SPI_Config(SPI_TypeDef *spi, SPI_ConfigTypedef *con);\n\nSPI_StatusTypedef BSP_SPI_Transmit(SPI_TypeDef *spi ,uint8_t *data,uint32_t size, uint32_t timeout);\n\nSPI_StatusTypedef BSP_SPI_Receive(SPI_TypeDef *spi ,uint8_t *data,uint32_t size, uint32_t timeout);\n\n\n#endif \/* SPI_BSP_H_ *\/\n<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">2. Modification of Source File:<\/h2>\n\n\n\n<p><\/p>\n\n\n\n<p>The function that reads from SPI 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_StatusTypedef BSP_SPI_Receive(SPI_TypeDef *spi ,uint8_t *data,uint32_t size, uint32_t timeout)\n{\n\tuint32_t start=BSP_Get_Ticks();\n\twhile(size)\n\t{\n\t\t\/*Send dummy data*\/\n\t\tspi-&gt;DR =0;\n\n\t\t\/*Wait for RXNE flag to be set*\/\n\t\twhile(!(spi-&gt;SR &amp; (SPI_SR_RXNE)))\n\t\t{\n\t\t\tif((BSP_Get_Ticks()-start)&gt;timeout){return SPI_Timeout;}\n\t\t}\n\n\t\t\/*Read data from data register*\/\n\t\t*data++ = (spi-&gt;DR);\n\t\tsize--;\n\t}\n\treturn SPI_Succuss;\n}<\/pre><\/div>\n\n\n\n<p>We start off by declaring local variable to hold the current ticks 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;}\">uint32_t start=BSP_Get_Ticks();<\/pre><\/div>\n\n\n\n<p>We shall go through size in while loop 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;}\">while(size)<\/pre><\/div>\n\n\n\n<p>Within the while loop.<\/p>\n\n\n\n<p>Send dummy data to keep the clock on SCK alive 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-&gt;DR =0;<\/pre><\/div>\n\n\n\n<p>Wait until the RXNE (Receiver buffer not empty):<\/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;}\">\/*Wait for RXNE flag to be set*\/\nwhile(!(spi-&gt;SR &amp; (SPI_SR_RXNE)))\n{\n  if((BSP_Get_Ticks()-start)&gt;timeout){return SPI_Timeout;}\n}<\/pre><\/div>\n\n\n\n<p>Within the while loop, we shall check for timeout by simply subtracting the current ticks from the stored one and if it is bigger than timeout, the function will return timeout.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>After the waiting:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Read the DR register.<\/li><li>Decrement the size variable.<\/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;}\">\/*Read data from data register*\/\n*data++ = (spi-&gt;DR);\nsize--;<\/pre><\/div>\n\n\n\n<p>Finally, return SPI_Success:<\/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;}\">return SPI_Succuss;<\/pre><\/div>\n\n\n\n<p>Hence, the updated source file:<\/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_bsp.h&quot;\n#include &quot;bsp.h&quot;\n\n\n\nvoid SPI_Enable_Clock(SPI_EnableTypedef spi_number)\n{\n\tswitch (spi_number)\n\t{\n\t\tcase spi1: RCC-&gt;APB2ENR|=RCC_APB2ENR_SPI1EN;\n\t\t\tbreak;\n\t\tcase spi2: RCC-&gt;APB1ENR|=RCC_APB1ENR_SPI2EN;\n\t\t\tbreak;\n\t\tcase spi3: RCC-&gt;APB1ENR|=RCC_APB1ENR_SPI3EN;\n\t\t\tbreak;\n\t\tcase spi4: RCC-&gt;APB2ENR|=RCC_APB2ENR_SPI4EN;\n\t\t\tbreak;\n\t\tcase spi5: RCC-&gt;APB2ENR|=RCC_APB2ENR_SPI5EN;\n\t\t\tbreak;\n\t\tdefault :\n\t\t\tbreak;\n\n\t}\n}\n\nvoid BSP_SPI_Config(SPI_TypeDef *spi, SPI_ConfigTypedef *con)\n{\n\n\tswitch (con-&gt;mode)\n\t{\n\n\t\t case Master_mode:  spi-&gt;CR1|=(1&lt;&lt;SPI_CR1_MSTR_Pos);\n\t\t \t break;\n\t\t case Slave_mode:   spi-&gt;CR1&amp;=~(1&lt;&lt;SPI_CR1_MSTR_Pos); break;\n\t\t default : break;\n\t}\n\n\tswitch (con-&gt;dataFromat)\n\t{\n\t\tcase MSB_First: spi-&gt;CR1&amp;=~(con-&gt;dataFromat&lt;&lt;SPI_CR1_LSBFIRST_Pos);\n\t\t\tbreak;\n\t\tcase LSB_First: spi-&gt;CR1|=(con-&gt;dataFromat&lt;&lt;SPI_CR1_LSBFIRST_Pos); break;\n\t\tdefault: break;\n\t}\n\n\tif(con-&gt;baud ==FCLK_2)\n\t{\n\t\tspi-&gt;CR1&amp;=~(SPI_CR1_BR_Msk&lt;&lt;SPI_CR1_BR_Pos);\n\t}\n\n\telse\n\t{\n\t\tspi-&gt;CR1|=(con-&gt;baud&lt;&lt;SPI_CR1_BR_Pos);\n\t}\n\n\n\n\tif (con-&gt;CPOL==CPOL0)\n\t{\n\t\tspi-&gt;CR1&amp;=~(1&lt;&lt;SPI_CR1_CPOL_Pos);\n\t}\n\telse\n\t{\n\t\tspi-&gt;CR1|=(con-&gt;CPOL&lt;&lt;SPI_CR1_CPOL_Pos);\n\t}\n\n\tif (con-&gt;CPHA==CPHA0)\n\t{\n\t\tspi-&gt;CR1&amp;=~(1&lt;&lt;SPI_CR1_CPHA_Pos);\n\t}\n\telse\n\t{\n\t\tspi-&gt;CR1|=(con-&gt;CPHA&lt;&lt;SPI_CR1_CPHA_Pos);\n\t}\n\n\n\n\tswitch (con-&gt;slaveManagement)\n\t{\n\t case software_slave: spi-&gt;CR1|=(1&lt;&lt;SPI_CR1_SSM_Pos)|(1&lt;&lt;SPI_CR1_SSI_Pos); break;\n\t case hardware_slave: spi-&gt;CR1&amp;=~((1&lt;&lt;SPI_CR1_SSM_Pos)|(1&lt;&lt;SPI_CR1_SSI_Pos)); break;\n\t default: break;\n\t}\n\n\tspi-&gt;CR1|=SPI_CR1_SPE;\n\n}\n\nSPI_StatusTypedef BSP_SPI_Transmit(SPI_TypeDef *spi ,uint8_t *data,uint32_t size, uint32_t timeout)\n{\n\n\tuint32_t i=0;\n\tuint32_t start=BSP_Get_Ticks();\n\twhile(i&lt;size)\n\t{\n\t\t\/*Wait until TXE is set*\/\n\t\twhile(!(spi-&gt;SR &amp; (SPI_SR_TXE)))\n\t\t{\n\t\t\tif((BSP_Get_Ticks()-start)&gt;timeout){return SPI_Timeout;}\n\t\t}\n\n\t\t\/*Write the data to the data register*\/\n\t\tspi-&gt;DR = data[i];\n\t\ti++;\n\n\t}\n\t\/*Wait until TXE is set*\/\n\twhile(!(spi-&gt;SR &amp; (SPI_SR_TXE))){if((BSP_Get_Ticks()-start)&gt;timeout){return SPI_Timeout;}}\n\n\t\/*Wait for BUSY flag to reset*\/\n\twhile((spi-&gt;SR &amp; (SPI_SR_BSY))){if((BSP_Get_Ticks()-start)&gt;timeout){return SPI_Timeout;}}\n\n\t\/*Clear OVR flag*\/\n\t(void)spi-&gt;DR;\n\t(void)spi-&gt;SR;\n\n\treturn SPI_Succuss;\n}\n\n\nSPI_StatusTypedef BSP_SPI_Receive(SPI_TypeDef *spi ,uint8_t *data,uint32_t size, uint32_t timeout)\n{\n\tuint32_t start=BSP_Get_Ticks();\n\twhile(size)\n\t{\n\t\t\/*Send dummy data*\/\n\t\tspi-&gt;DR =0;\n\n\t\t\/*Wait for RXNE flag to be set*\/\n\t\twhile(!(spi-&gt;SR &amp; (SPI_SR_RXNE)))\n\t\t{\n\t\t\tif((BSP_Get_Ticks()-start)&gt;timeout){return SPI_Timeout;}\n\t\t}\n\n\t\t\/*Read data from data register*\/\n\t\t*data++ = (spi-&gt;DR);\n\t\tsize--;\n\t}\n\treturn SPI_Succuss;\n}\n<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">3. Main code:<\/h2>\n\n\n\n<p>Since this guide uses MPU9250 as slave device, you can take a look at <a rel=\"noreferrer noopener\" href=\"https:\/\/blog.embeddedexpert.io\/?p=1743\" data-type=\"URL\" data-id=\"https:\/\/blog.embeddedexpert.io\/?p=1743\" target=\"_blank\">this guide<\/a> for how to connect MPU9250 in SPI.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>The main.c 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;}\">#include &quot;bsp.h&quot;\n#include &quot;uart_bsp.h&quot;\n#include &quot;exti_bsp.h&quot;\n#include &quot;bsp_debug.h&quot;\n#include &quot;spi_bsp.h&quot;\n\n\n\n\nvoid clock_config(void);\n\n\nuint8_t accData[6];\n\nGPIO_Output_Typedef CS_Pin;\n\n#define READ_FLAG 0x80\n\n\nint main()\n{\n\n\n\t#if FPU_EN\n\t\tSCB-&gt;CPACR |= ((3UL &lt;&lt; 10*2)|(3UL &lt;&lt; 11*2));\n\t#endif\n\n\tclock_config();\n\tBSP_Ticks_Init(100000000);\n\n\tGPIO_Configure_Typedef PA5_SPI,PA6_SPI,PA7_SPI;\n\n\tGPIOA_CLOCK_ENABLE();\n\n\tPA5_SPI.PinNumber=5;\n\tPA5_SPI.Mode=Alternate_function;\n\tPA5_SPI.AlternateType=AF5;\n\tPA5_SPI.OutPutspeed=High_Speed;\n\n\n\tPA6_SPI.PinNumber=6;\n\tPA6_SPI.Mode=Alternate_function;\n\tPA6_SPI.AlternateType=AF5;\n\tPA6_SPI.OutPutspeed=High_Speed;\n\n\tPA7_SPI.PinNumber=7;\n\tPA7_SPI.Mode=Alternate_function;\n\tPA7_SPI.AlternateType=AF5;\n\tPA6_SPI.OutPutspeed=High_Speed;\n\n\tGPIO_Initialization(GPIOA,&amp;PA5_SPI);\n\tGPIO_Initialization(GPIOA,&amp;PA6_SPI);\n\tGPIO_Initialization(GPIOA,&amp;PA7_SPI);\n\n\n\tGPIO_Configure_Typedef CS_Pin_Config;\n\n\tCS_Pin_Config.PinNumber=pin0;\n\tCS_Pin_Config.Mode=OUTPUT;\n\tCS_Pin_Config.OutPutspeed=High_Speed;\n\n\tGPIO_Initialization(GPIOA,&amp;CS_Pin_Config);\n\n\tGPIO_WritePin(GPIOA,&amp;CS_Pin,Set);\n\n\tSPI_Enable_Clock(spi1);\n\n\tSPI_ConfigTypedef cSPI1;\n\n\tcSPI1.mode=Master_mode;\n\tcSPI1.slaveManagement=software_slave;\n\tcSPI1.baud=FCLK_8;\n\tcSPI1.CPHA=CPHA0;\n\tcSPI1.CPOL=CPOL0;\n\tcSPI1.LSBFirst=MSB_First;\n\n\n\tBSP_SPI_Config(SPI1,&amp;cSPI1);\n\tuint8_t addData=0x3B|READ_FLAG;\n\twhile(1)\n\t{\n\t\tGPIO_WritePin(GPIOA,&amp;CS_Pin,Reset);\n\n\t\tBSP_SPI_Transmit(SPI1,&amp;addData,1,100);\n\n\t\tBSP_SPI_Receive(SPI1,accData,6,100);\n\n\t\tGPIO_WritePin(GPIOA,&amp;CS_Pin,Set);\n\n\t\tBSP_Delay(10);\n\n\t}\n}\n\nvoid clock_config(void)\n{\n\tClock_Config_Typedef clockConfig;\n\n\tclockConfig.PLL_M= 4;\n\tclockConfig.PLL_N= 200;\n\tclockConfig.PLL_P= 4;\n\n\tclockConfig.AHB1Prescaler=AHB1_Prescaler1;\n\tclockConfig.APB1Prescaler=APB1_Prescaler2;\n\tclockConfig.APB2Prescaler=APB2_Prescaler1;\n\n\tclockConfig.clockSourc=External_Oscillator;\n\tclockConfig.flash_latency= Three_wait_state;\n\n\tClock_Configuration(&amp;clockConfig);\n}\n\n<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">4. Results:<\/h2>\n\n\n\n<p>Open the debug session and set accData as variable in live expression, you should get the following results:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"477\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/08\/Screenshot-2023-08-05-at-5.05.25-PM-1024x477.png\" alt=\"\" class=\"wp-image-1925\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/08\/Screenshot-2023-08-05-at-5.05.25-PM-1024x477.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/08\/Screenshot-2023-08-05-at-5.05.25-PM-300x140.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/08\/Screenshot-2023-08-05-at-5.05.25-PM-768x358.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/08\/Screenshot-2023-08-05-at-5.05.25-PM-1150x536.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/08\/Screenshot-2023-08-05-at-5.05.25-PM-750x350.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/08\/Screenshot-2023-08-05-at-5.05.25-PM-400x186.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/08\/Screenshot-2023-08-05-at-5.05.25-PM-250x117.png 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/08\/Screenshot-2023-08-05-at-5.05.25-PM.png 1412w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>This proofs that the SPI in full duplex is working.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Happy coding \ud83d\ude42<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this twelfth part of Board Support Package, we shall develop the receiver part of SPI to achieve full duplex communication with slave device which is in this case, MPU9250 sensor. In this guide, we shall cover the following: Modification of header file. Modification of source file. Main code. Results. 1. Modification of Header File: [&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-1923","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\/1923"}],"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=1923"}],"version-history":[{"count":1,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/1923\/revisions"}],"predecessor-version":[{"id":1926,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/1923\/revisions\/1926"}],"wp:attachment":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1923"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1923"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1923"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}