1 | /**
|
2 | ******************************************************************************
|
3 | * @file SPI/DMA/main.c
|
4 | * @author MCD Application Team
|
5 | * @version V3.5.0
|
6 | * @date 08-April-2011
|
7 | * @brief Main program body
|
8 | ******************************************************************************
|
9 | * @attention
|
10 | *
|
11 | * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
|
12 | * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
|
13 | * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
|
14 | * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
|
15 | * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
|
16 | * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
|
17 | *
|
18 | * <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2>
|
19 | ******************************************************************************
|
20 | */
|
21 |
|
22 | /* Includes ------------------------------------------------------------------*/
|
23 | #include "stm32f10x.h"
|
24 | #include "platform_config.h"
|
25 |
|
26 |
|
27 | /** @addtogroup STM32F10x_StdPeriph_Examples
|
28 | * @{
|
29 | */
|
30 |
|
31 | /** @addtogroup SPI_DMA
|
32 | * @{
|
33 | */
|
34 |
|
35 | /* Private typedef -----------------------------------------------------------*/
|
36 | typedef enum {FAILED = 0, PASSED = !FAILED} TestStatus;
|
37 |
|
38 | /* Private define ------------------------------------------------------------*/
|
39 | #define BufferSize 32
|
40 |
|
41 | /* Private macro -------------------------------------------------------------*/
|
42 | /* Private variables ---------------------------------------------------------*/
|
43 | SPI_InitTypeDef SPI_InitStructure;
|
44 | DMA_InitTypeDef DMA_InitStructure;
|
45 | GPIO_InitTypeDef GPIO_InitStructure;
|
46 |
|
47 | uint8_t SPI_MASTER_Buffer_Tx[BufferSize] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
|
48 | 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
|
49 | 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12,
|
50 | 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
|
51 | 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E,
|
52 | 0x1F, 0x20};
|
53 | uint8_t SPI_SLAVE_Buffer_Rx[BufferSize];
|
54 | __IO uint8_t TxIdx = 0;
|
55 | volatile TestStatus TransferStatus = FAILED;
|
56 |
|
57 |
|
58 | /* Private function prototypes -----------------------------------------------*/
|
59 | void RCC_Configuration(void);
|
60 | void GPIO_Configuration(void);
|
61 | TestStatus Buffercmp(uint8_t* pBuffer1, uint8_t* pBuffer2, uint16_t BufferLength);
|
62 |
|
63 | /* Private functions ---------------------------------------------------------*/
|
64 |
|
65 | /**
|
66 | * @brief Main program
|
67 | * @param None
|
68 | * @retval None
|
69 | */
|
70 | int main(void)
|
71 | {
|
72 | /*!< At this stage the microcontroller clock setting is already configured,
|
73 | this is done through SystemInit() function which is called from startup
|
74 | file (startup_stm32f10x_xx.s) before to branch to application main.
|
75 | To reconfigure the default setting of SystemInit() function, refer to
|
76 | system_stm32f10x.c file
|
77 | */
|
78 |
|
79 | /* System clocks configuration ---------------------------------------------*/
|
80 | RCC_Configuration();
|
81 |
|
82 | /* GPIO configuration ------------------------------------------------------*/
|
83 | GPIO_Configuration();
|
84 |
|
85 | /* SPI_SLAVE_Rx_DMA_Channel configuration ---------------------------------------------*/
|
86 | DMA_DeInit(SPI_SLAVE_Rx_DMA_Channel);
|
87 | DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)SPI_SLAVE_DR_Base;
|
88 | DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)SPI_SLAVE_Buffer_Rx;
|
89 | DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
|
90 | DMA_InitStructure.DMA_BufferSize = BufferSize;
|
91 | DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
|
92 | DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
|
93 | DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
|
94 | DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
|
95 | DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
|
96 | DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
|
97 | DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
|
98 | DMA_Init(SPI_SLAVE_Rx_DMA_Channel, &DMA_InitStructure);
|
99 |
|
100 | /* SPI_MASTER configuration ------------------------------------------------------*/
|
101 | SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Tx;
|
102 | SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
|
103 | SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
|
104 | SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
|
105 | SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
|
106 | SPI_InitStructure.SPI_NSS = SPI_NSS_Hard;
|
107 | SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
|
108 | SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
|
109 | SPI_InitStructure.SPI_CRCPolynomial = 7;
|
110 | SPI_Init(SPI_MASTER, &SPI_InitStructure);
|
111 |
|
112 | /* SPI_SLAVE configuration ------------------------------------------------------*/
|
113 | SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Rx;
|
114 | SPI_InitStructure.SPI_Mode = SPI_Mode_Slave;
|
115 | SPI_Init(SPI_SLAVE, &SPI_InitStructure);
|
116 |
|
117 | /* Enable SPI_MASTER NSS output for master mode */
|
118 | SPI_SSOutputCmd(SPI_MASTER, ENABLE);
|
119 |
|
120 | /* Enable SPI_SLAVE Rx request */
|
121 | SPI_I2S_DMACmd(SPI_SLAVE, SPI_I2S_DMAReq_Rx, ENABLE);
|
122 |
|
123 | /* Enable SPI_SLAVE */
|
124 | SPI_Cmd(SPI_SLAVE, ENABLE);
|
125 | /* Enable SPI_MASTER */
|
126 | SPI_Cmd(SPI_MASTER, ENABLE);
|
127 |
|
128 | /* Enable DMA1 Channel4 */
|
129 | DMA_Cmd(SPI_SLAVE_Rx_DMA_Channel, ENABLE);
|
130 |
|
131 | /* Transfer procedure */
|
132 | while (TxIdx < BufferSize)
|
133 | {
|
134 | /* Wait for SPI_MASTER Tx buffer empty */
|
135 | while (SPI_I2S_GetFlagStatus(SPI_MASTER, SPI_I2S_FLAG_TXE) == RESET);
|
136 | /* Send SPI_MASTER data */
|
137 | SPI_I2S_SendData(SPI_MASTER, SPI_MASTER_Buffer_Tx[TxIdx++]);
|
138 | }
|
139 |
|
140 | /* Wait for DMA1 channel4 transfer complete */
|
141 | while (!DMA_GetFlagStatus(SPI_SLAVE_Rx_DMA_FLAG));
|
142 |
|
143 | /* Check the correctness of written data */
|
144 | TransferStatus = Buffercmp(SPI_SLAVE_Buffer_Rx, SPI_MASTER_Buffer_Tx, BufferSize);
|
145 | /* TransferStatus = PASSED, if the transmitted and received data
|
146 | are equal */
|
147 | /* TransferStatus = FAILED, if the transmitted and received data
|
148 | are different */
|
149 |
|
150 | while (1)
|
151 | {}
|
152 | }
|
153 |
|
154 | /**
|
155 | * @brief Configures the different system clocks.
|
156 | * @param None
|
157 | * @retval None
|
158 | */
|
159 | void RCC_Configuration(void)
|
160 | {
|
161 | /* PCLK2 = HCLK/2 */
|
162 | RCC_PCLK2Config(RCC_HCLK_Div2);
|
163 |
|
164 | /* Enable peripheral clocks --------------------------------------------------*/
|
165 | /* Enable SPI_SLAVE DMA clock */
|
166 | RCC_AHBPeriphClockCmd(SPI_SLAVE_DMA_CLK, ENABLE);
|
167 |
|
168 | #ifdef USE_STM3210C_EVAL
|
169 | /* Enable GPIO clock for SPI_MASTER and SPI_SLAVE */
|
170 | RCC_APB2PeriphClockCmd(SPI_MASTER_GPIO_CLK | SPI_SLAVE_GPIO_CLK |
|
171 | RCC_APB2Periph_AFIO, ENABLE);
|
172 |
|
173 | /* Enable SPI_MASTER Periph clock */
|
174 | RCC_APB1PeriphClockCmd(SPI_MASTER_CLK, ENABLE);
|
175 |
|
176 | #else
|
177 | /* Enable SPI_MASTER clock and GPIO clock for SPI_MASTER and SPI_SLAVE */
|
178 | RCC_APB2PeriphClockCmd(SPI_MASTER_GPIO_CLK | SPI_SLAVE_GPIO_CLK |
|
179 | SPI_MASTER_CLK, ENABLE);
|
180 | #endif
|
181 | /* Enable SPI_SLAVE Periph clock */
|
182 | RCC_APB1PeriphClockCmd(SPI_SLAVE_CLK, ENABLE);
|
183 | }
|
184 |
|
185 | /**
|
186 | * @brief Configures the different GPIO ports.
|
187 | * @param None
|
188 | * @retval None
|
189 | */
|
190 | void GPIO_Configuration(void)
|
191 | {
|
192 | GPIO_InitTypeDef GPIO_InitStructure;
|
193 |
|
194 | #ifdef USE_STM3210C_EVAL
|
195 | /* Enable SPI3 Pins Software Remapping */
|
196 | GPIO_PinRemapConfig(GPIO_Remap_SPI3, ENABLE);
|
197 |
|
198 | /* Configure SPI_MASTER pins: SCK and MOSI */
|
199 | GPIO_InitStructure.GPIO_Pin = SPI_MASTER_PIN_SCK | SPI_MASTER_PIN_MOSI;
|
200 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
201 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
|
202 | GPIO_Init(SPI_MASTER_GPIO, &GPIO_InitStructure);
|
203 |
|
204 | /* Configure SPI_MASTER NSS pin */
|
205 | GPIO_InitStructure.GPIO_Pin = SPI_MASTER_PIN_NSS;
|
206 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
207 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
|
208 | GPIO_Init(SPI_MASTER_GPIO_NSS, &GPIO_InitStructure);
|
209 |
|
210 | #else
|
211 | /* Configure SPI_MASTER pins: NSS, SCK and MOSI */
|
212 | GPIO_InitStructure.GPIO_Pin = SPI_MASTER_PIN_NSS | SPI_MASTER_PIN_SCK | SPI_MASTER_PIN_MOSI;
|
213 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
214 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
|
215 | GPIO_Init(SPI_MASTER_GPIO, &GPIO_InitStructure);
|
216 | #endif
|
217 |
|
218 | /* Configure SPI_SLAVE pins: NSS, SCK and MISO*/
|
219 | GPIO_InitStructure.GPIO_Pin = SPI_SLAVE_PIN_NSS | SPI_SLAVE_PIN_SCK;
|
220 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
|
221 | GPIO_Init(SPI_SLAVE_GPIO, &GPIO_InitStructure);
|
222 |
|
223 | GPIO_InitStructure.GPIO_Pin = SPI_SLAVE_PIN_MISO;
|
224 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
|
225 | GPIO_Init(SPI_SLAVE_GPIO, &GPIO_InitStructure);
|
226 |
|
227 | }
|
228 |
|
229 | /**
|
230 | * @brief Compares two buffers.
|
231 | * @param pBuffer1, pBuffer2: buffers to be compared.
|
232 | * @param BufferLength: buffer's length
|
233 | * @retval PASSED: pBuffer1 identical to pBuffer2
|
234 | * FAILED: pBuffer1 differs from pBuffer2
|
235 | */
|
236 | TestStatus Buffercmp(uint8_t* pBuffer1, uint8_t* pBuffer2, uint16_t BufferLength)
|
237 | {
|
238 | while (BufferLength--)
|
239 | {
|
240 | if (*pBuffer1 != *pBuffer2)
|
241 | {
|
242 | return FAILED;
|
243 | }
|
244 |
|
245 | pBuffer1++;
|
246 | pBuffer2++;
|
247 | }
|
248 |
|
249 | return PASSED;
|
250 | }
|
251 |
|
252 | #ifdef USE_FULL_ASSERT
|
253 |
|
254 | /**
|
255 | * @brief Reports the name of the source file and the source line number
|
256 | * where the assert_param error has occurred.
|
257 | * @param file: pointer to the source file name
|
258 | * @param line: assert_param error line source number
|
259 | * @retval None
|
260 | */
|
261 | void assert_failed(uint8_t* file, uint32_t line)
|
262 | {
|
263 | /* User can add his own implementation to report the file name and line number,
|
264 | ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
|
265 |
|
266 | /* Infinite loop */
|
267 | while (1)
|
268 | {}
|
269 | }
|
270 |
|
271 | #endif
|
272 |
|
273 | /**
|
274 | * @}
|
275 | */
|
276 |
|
277 | /**
|
278 | * @}
|
279 | */
|
280 |
|
281 | /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
|