1 | /*----------------------------------------------------------------------------
|
2 | * RL-ARM - FlashFS
|
3 | *----------------------------------------------------------------------------
|
4 | * Name: SPI_STM32F107.c
|
5 | * Purpose: Serial Peripheral Interface Driver for ST STM32F105/7
|
6 | * Rev.: V4.20
|
7 | *----------------------------------------------------------------------------
|
8 | * This code is part of the RealView Run-Time Library.
|
9 | * Copyright (c) 2004-2011 KEIL - An ARM Company. All rights reserved.
|
10 | *---------------------------------------------------------------------------*/
|
11 |
|
12 | #include <stdio.h>
|
13 | #include <File_Config.h>
|
14 | #include "stm32f2xx.h" /* STM32F2 Library Definitions */
|
15 |
|
16 |
|
17 | /*----------------------------------------------------------------------------
|
18 | SPI Driver instance definition
|
19 | spi0_drv: First SPI driver
|
20 | spi1_drv: Second SPI driver
|
21 | *---------------------------------------------------------------------------*/
|
22 |
|
23 | #define __DRV_ID spi0_drv
|
24 | #define __FPCLK 72000000
|
25 |
|
26 | /* SPI Driver Interface functions */
|
27 | static BOOL Init (void);
|
28 | static BOOL UnInit (void);
|
29 | static U8 Send (U8 outb);
|
30 | static BOOL SendBuf (U8 *buf, U32 sz);
|
31 | static BOOL RecBuf (U8 *buf, U32 sz);
|
32 | static BOOL BusSpeed (U32 kbaud);
|
33 | static BOOL SetSS (U32 ss);
|
34 | static U32 CheckMedia (void); /* Optional function for SD card check */
|
35 |
|
36 | /* SPI Device Driver Control Block */
|
37 | SPI_DRV __DRV_ID = {
|
38 | Init,
|
39 | UnInit,
|
40 | Send,
|
41 | SendBuf,
|
42 | RecBuf,
|
43 | BusSpeed,
|
44 | SetSS,
|
45 | CheckMedia /* Can be NULL if not existing */
|
46 | };
|
47 |
|
48 |
|
49 | #define SPIx SPI1
|
50 |
|
51 |
|
52 | /* SPI_SR - bit definitions. */
|
53 | #define RXNE 0x01
|
54 | #define TXE 0x02
|
55 | #define BSY 0x80
|
56 | #define FPCLK __FPCLK/1000
|
57 |
|
58 |
|
59 | /*--------------------------- spi_init --------------------------------------*/
|
60 |
|
61 | static BOOL Init (void)
|
62 | {
|
63 | GPIO_InitTypeDef GPIO_InitStructure;
|
64 | SPI_InitTypeDef SPI_InitStructure;
|
65 |
|
66 | RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
|
67 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
|
68 |
|
69 | // Card Sensor PA.8 input
|
70 | // 1 = NO Card, 0 = Card plugged.
|
71 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
|
72 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
|
73 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
74 | GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
75 | GPIO_Init(GPIOA, &GPIO_InitStructure);
|
76 |
|
77 | // Card Locked PB.0 input
|
78 | // 1 = Card locked, 0 = Card unlocked.
|
79 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
|
80 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
|
81 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
82 | GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
83 | GPIO_Init(GPIOB, &GPIO_InitStructure);
|
84 |
|
85 |
|
86 | // Configure SPI as alternate function
|
87 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
|
88 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
|
89 | GPIO_Init(GPIOA, &GPIO_InitStructure);
|
90 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
|
91 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
|
92 | GPIO_Init(GPIOA, &GPIO_InitStructure);
|
93 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
|
94 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
|
95 | GPIO_Init(GPIOA, &GPIO_InitStructure);
|
96 |
|
97 | // Map the USART1 alternate function
|
98 | GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_SPI1);
|
99 | GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_SPI1);
|
100 | GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_SPI1);
|
101 |
|
102 | // Configure PA4 (/CS) as output
|
103 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
|
104 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
|
105 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
106 | GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
|
107 | GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
108 | GPIO_Init(GPIOA, &GPIO_InitStructure);
|
109 |
|
110 |
|
111 |
|
112 | SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
|
113 | SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
|
114 | SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
|
115 | SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
|
116 | SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
|
117 | SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
|
118 | SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;
|
119 | SPI_Init(SPI1,&SPI_InitStructure);
|
120 | SPI_Cmd(SPI1, ENABLE);
|
121 | return (__TRUE);
|
122 | }
|
123 |
|
124 |
|
125 | /*--------------------------- UnInit ----------------------------------------*/
|
126 |
|
127 | static BOOL UnInit (void)
|
128 | {
|
129 | /* Return SSP interface to default state. */
|
130 | /*
|
131 | GPIOA->CRL = (GPIOA->CRL & 0x0000FFFF) | 0x44440000;
|
132 |
|
133 |
|
134 | GPIOE->ODR &= ~0x01;
|
135 | GPIOE->CRL = (GPIOE->CRL & 0xFFFFFFF0) | 0x00000004;
|
136 |
|
137 | SPIx->CR1 = 0x0000;
|
138 | SPIx->CR2 = 0x0000;
|
139 | */
|
140 | return (__TRUE);
|
141 | }
|
142 |
|
143 |
|
144 |
|
145 | /*--------------------------- Send ------------------------------------------*/
|
146 |
|
147 | static U8 Send (U8 outb) {
|
148 | /* Write and Read a byte on SPI interface. */
|
149 |
|
150 | SPIx->DR = outb;
|
151 | /* Wait if RNE cleared, Rx FIFO is empty. */
|
152 | while (!(SPIx->SR & RXNE));
|
153 | return (SPIx->DR);
|
154 | }
|
155 |
|
156 |
|
157 | /*--------------------------- SendBuf ---------------------------------------*/
|
158 |
|
159 | static BOOL SendBuf (U8 *buf, U32 sz) {
|
160 | /* Send buffer to SPI interface. */
|
161 | U32 i;
|
162 |
|
163 | for (i = 0; i < sz; i++) {
|
164 | SPIx->DR = buf[i];
|
165 | /* Wait if TXE cleared, Tx FIFO is full. */
|
166 | while (!(SPIx->SR & TXE));
|
167 |
|
168 | SPIx->DR;
|
169 | }
|
170 | /* Wait until Tx finished, drain Rx FIFO. */
|
171 | while (SPIx->SR & (BSY | RXNE)) {
|
172 | SPIx->DR;
|
173 | }
|
174 | return (__TRUE);
|
175 | }
|
176 |
|
177 |
|
178 | /*--------------------------- RecBuf ----------------------------------------*/
|
179 |
|
180 | static BOOL RecBuf (U8 *buf, U32 sz) {
|
181 | /* Receive SPI data to buffer. */
|
182 | U32 i;
|
183 |
|
184 | for (i = 0; i < sz; i++) {
|
185 | SPIx->DR = 0xFF;
|
186 | /* Wait if RNE cleared, Rx FIFO is empty. */
|
187 | while (!(SPIx->SR & RXNE));
|
188 | buf[i] = SPIx->DR;
|
189 | }
|
190 | return (__TRUE);
|
191 | }
|
192 |
|
193 |
|
194 | /*--------------------------- BusSpeed --------------------------------------*/
|
195 |
|
196 | static BOOL BusSpeed (U32 kbaud) {
|
197 | /* Set an SPI clock to required baud rate. */
|
198 | U8 br;
|
199 |
|
200 | if (kbaud >= FPCLK / 2) br = 0; /* FPCLK/2 */
|
201 | else if (kbaud >= FPCLK / 4) br = 1; /* FPCLK/4 */
|
202 | else if (kbaud >= FPCLK / 8) br = 2; /* FPCLK/8 */
|
203 | else if (kbaud >= FPCLK / 16) br = 3; /* FPCLK/16 */
|
204 | else if (kbaud >= FPCLK / 32) br = 4; /* FPCLK/32 */
|
205 | else if (kbaud >= FPCLK / 64) br = 5; /* FPCLK/64 */
|
206 | else if (kbaud >= FPCLK / 128) br = 6; /* FPCLK/128 */
|
207 | else br = 7; /* FPCLK/256 */
|
208 |
|
209 | SPIx->CR1 = (SPIx->CR1 & ~(7 << 3)) | (br << 3);
|
210 |
|
211 | return (__TRUE);
|
212 | }
|
213 |
|
214 |
|
215 | /*--------------------------- SetSS -----------------------------------------*/
|
216 |
|
217 | static BOOL SetSS (U32 ss) {
|
218 | /* Enable/Disable SPI Chip Select (drive it high or low). */
|
219 | if (ss)
|
220 | {
|
221 | printf ("High\n");
|
222 | GPIO_SetBits (GPIOA, GPIO_Pin_4); /* SSEL is GPIO, output set to high. */
|
223 | }
|
224 | else
|
225 | {
|
226 | printf ("Low\n");
|
227 | GPIO_ResetBits (GPIOA, GPIO_Pin_4); /* SSEL is GPIO, output set to low. */
|
228 | }
|
229 | return (__TRUE);
|
230 | }
|
231 |
|
232 |
|
233 | /*--------------------------- CheckMedia ------------------------------------*/
|
234 |
|
235 | static U32 CheckMedia (void) {
|
236 | /* Read CardDetect and WriteProtect SD card socket pins. */
|
237 | U32 stat = 0;
|
238 |
|
239 | if (!GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_8))
|
240 | {
|
241 | printf("Card inserted\n");
|
242 | /* Card is inserted (CD=0). */
|
243 | stat |= M_INSERTED;
|
244 | }
|
245 | #if 0
|
246 | if (GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_0))
|
247 | {
|
248 | printf("Card locked\n");
|
249 | /* Write Protect switch is active (WP=1). */
|
250 | stat |= M_PROTECTED;
|
251 | }
|
252 | #endif
|
253 | return (stat);
|
254 | }
|
255 |
|
256 | /*----------------------------------------------------------------------------
|
257 | * end of file
|
258 | *---------------------------------------------------------------------------*/
|