{"id":1919,"date":"2023-08-03T08:14:40","date_gmt":"2023-08-03T08:14:40","guid":{"rendered":"https:\/\/blog.embeddedexpert.io\/?p=1919"},"modified":"2023-08-03T08:14:43","modified_gmt":"2023-08-03T08:14:43","slug":"building-board-support-package-bsp-for-stm32f411-nucleo64-part11-spi-tx-mode","status":"publish","type":"post","link":"https:\/\/blog.embeddedexpert.io\/?p=1919","title":{"rendered":"Building Board Support Package (BSP) for STM32F411-Nucleo64 Part11: SPI TX Mode"},"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-1024x683.jpeg\" alt=\"\" class=\"wp-image-1920\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/08\/AdobeStock_128586024-1024x683.jpeg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/08\/AdobeStock_128586024-300x200.jpeg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/08\/AdobeStock_128586024-768x512.jpeg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/08\/AdobeStock_128586024-1536x1024.jpeg 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/08\/AdobeStock_128586024-2048x1365.jpeg 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/08\/AdobeStock_128586024-1150x767.jpeg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/08\/AdobeStock_128586024-750x500.jpeg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/08\/AdobeStock_128586024-400x267.jpeg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/08\/AdobeStock_128586024-250x167.jpeg 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>In this eleventh part of Board Support Package (BSP), we shall develop SPI driver to send multiple bytes with timeout.<\/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>Developing the header file.<\/li><li>Developing the source file.<\/li><li>Code test.<\/li><li>Results.<\/li><\/ul>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">1. Developing The Header File:<\/h2>\n\n\n\n<p>Before heading into developing the header file, you can refer to <a href=\"https:\/\/blog.embeddedexpert.io\/?p=466\" data-type=\"URL\" data-id=\"https:\/\/blog.embeddedexpert.io\/?p=466\" target=\"_blank\" rel=\"noreferrer noopener\">this<\/a> guide about SPI and how to configure it.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Create new header file with name of spi_bsp.h.<\/p>\n\n\n\n<p>Within the header file, include the 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;stdint.h&quot;\n#include &quot;stm32f4xx.h&quot;<\/pre><\/div>\n\n\n\n<p>Since there are multiple SPI in STM32F411, we shall declare the following enum for clock enable functionality:<\/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\tspi1=0,\n\tspi2=1,\n\tspi3=2,\n\tspi4=3,\n\tspi5=4\n}SPI_EnableTypedef;<\/pre><\/div>\n\n\n\n<p>Also, we shall declare enum to handle the status of the transmission 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\tSPI_Succuss=0,\n\tSPI_Timeout=1,\n\n}SPI_StatusTypedef;<\/pre><\/div>\n\n\n\n<p>Also, declare enum to handle the configuration 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\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;<\/pre><\/div>\n\n\n\n<p>The configurations as following:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Data format: 8-bit or 16-bit.<\/li><li>Software or hardware slave management.<\/li><li>MSB or LSB first.<\/li><li>Baudrate<\/li><li>Master or slave mode.<\/li><li>CPOL and CPHA mode.<\/li><\/ul>\n\n\n\n<p>Also, we shall create a structure to handle the configuration 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 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;<\/pre><\/div>\n\n\n\n<p>Declare the following 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_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);<\/pre><\/div>\n\n\n\n<p>Hence, the 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\n\n\n#endif \/* SPI_BSP_H_ *\/<\/pre><\/div>\n\n\n\n<p>Thats all for the header file.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">2. Developing The Source File:<\/h2>\n\n\n\n<p><\/p>\n\n\n\n<p>Create new source file with name of spi_bsp.c.<\/p>\n\n\n\n<p>Within the source file, include the following header files:<\/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;<\/pre><\/div>\n\n\n\n<p>For SPI clock enable 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_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}<\/pre><\/div>\n\n\n\n<p>The function takes SPI_EnableTypedef as argument to enable which SPI.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>For SPI configuration 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 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<\/pre><\/div>\n\n\n\n<p>For SPI transmit 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;}\">SPI_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<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>Hence, the entire source code 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;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<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">3. Code Test:<\/h2>\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;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 SPI_TX_Data[5]={0x10,0x12,0x14,0x16,0x18};\n\nGPIO_Output_Typedef CS_Pin;\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_64;\n\tcSPI1.CPHA=CPHA0;\n\tcSPI1.CPOL=CPOL0;\n\tcSPI1.LSBFirst=MSB_First;\n\n\n\tBSP_SPI_Config(SPI1,&amp;cSPI1);\n\n\twhile(1)\n\t{\n\t\tGPIO_WritePin(GPIOA,&amp;CS_Pin,Reset);\n\n\t\tBSP_SPI_Transmit(SPI1,SPI_TX_Data,5,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>By using logic analyzer, connect pins PA0(CS), PA5 (SCK) and PA7 (MOSI) to logic analyzer and you should get the following results:<\/p>\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=\"426\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/08\/Screenshot-2023-08-03-at-10.29.32-AM-1024x426.png\" alt=\"\" class=\"wp-image-1921\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/08\/Screenshot-2023-08-03-at-10.29.32-AM-1024x426.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/08\/Screenshot-2023-08-03-at-10.29.32-AM-300x125.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/08\/Screenshot-2023-08-03-at-10.29.32-AM-768x320.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/08\/Screenshot-2023-08-03-at-10.29.32-AM-1536x639.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/08\/Screenshot-2023-08-03-at-10.29.32-AM-1150x479.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/08\/Screenshot-2023-08-03-at-10.29.32-AM-750x312.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/08\/Screenshot-2023-08-03-at-10.29.32-AM-400x166.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/08\/Screenshot-2023-08-03-at-10.29.32-AM-250x104.png 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/08\/Screenshot-2023-08-03-at-10.29.32-AM.png 1980w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Happy coding \ud83d\ude42<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this eleventh part of Board Support Package (BSP), we shall develop SPI driver to send multiple bytes with timeout. In this guide, we shall cover the following: Developing the header file. Developing the source file. Code test. Results. 1. Developing The Header File: Before heading into developing the header file, you can refer to [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3,2,11,12],"tags":[],"class_list":["post-1919","post","type-post","status-publish","format-standard","hentry","category-data-structures","category-embedded-systems","category-peripheral-drivers","category-stm32"],"_links":{"self":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/1919"}],"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=1919"}],"version-history":[{"count":1,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/1919\/revisions"}],"predecessor-version":[{"id":1922,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/1919\/revisions\/1922"}],"wp:attachment":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1919"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1919"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1919"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}