OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [freertos-6.1.1/] [Demo/] [CORTEX_STM32F103_GCC_Rowley/] [Drivers/] [SPI_Flash_ST_Eval.c] - Blame information for rev 582

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 582 jeremybenn
/******************** (C) COPYRIGHT 2009 STMicroelectronics ********************
2
* File Name          : spi_flash.c
3
* Author             : MCD Application Team
4
* Version            : V2.0.0
5
* Date               : 04/27/2009
6
* Description        : This file provides a set of functions needed to manage the
7
*                      communication between SPI peripheral and SPI M25P64 FLASH.
8
********************************************************************************
9
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
10
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
11
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
12
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
13
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
14
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
15
*******************************************************************************/
16
 
17
/* Includes ------------------------------------------------------------------*/
18
#include "SPI_Flash_ST_Eval.h"
19
 
20
/* Private typedef -----------------------------------------------------------*/
21
#define SPI_FLASH_PageSize    0x100
22
 
23
/* Private define ------------------------------------------------------------*/
24
#define WRITE      0x02  /* Write to Memory instruction */
25
#define WRSR       0x01  /* Write Status Register instruction */
26
#define WREN       0x06  /* Write enable instruction */
27
 
28
#define READ       0x03  /* Read from Memory instruction */
29
#define RDSR       0x05  /* Read Status Register instruction  */
30
#define RDID       0x9F  /* Read identification */
31
#define SE         0xD8  /* Sector Erase instruction */
32
#define BE         0xC7  /* Bulk Erase instruction */
33
 
34
#define WIP_Flag   0x01  /* Write In Progress (WIP) flag */
35
 
36
#define Dummy_Byte 0xA5
37
 
38
/* Private macro -------------------------------------------------------------*/
39
/* Private variables ---------------------------------------------------------*/
40
/* Private function prototypes -----------------------------------------------*/
41
/* Private functions ---------------------------------------------------------*/
42
 
43
/*******************************************************************************
44
* Function Name  : SPI_FLASH_Init
45
* Description    : Initializes the peripherals used by the SPI FLASH driver.
46
* Input          : None
47
* Output         : None
48
* Return         : None
49
*******************************************************************************/
50
void SPI_FLASH_Init(void)
51
{
52
  SPI_InitTypeDef  SPI_InitStructure;
53
  GPIO_InitTypeDef GPIO_InitStructure;
54
 
55
  /* Enable SPI1 and GPIO clocks */
56
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1 | RCC_APB2Periph_GPIOA |
57
                         RCC_APB2Periph_GPIO_CS, ENABLE);
58
 
59
  /* Configure SPI1 pins: SCK, MISO and MOSI */
60
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
61
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
62
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
63
  GPIO_Init(GPIOA, &GPIO_InitStructure);
64
 
65
  /* Configure I/O for Flash Chip select */
66
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_CS;
67
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
68
  GPIO_Init(GPIO_CS, &GPIO_InitStructure);
69
 
70
  /* Deselect the FLASH: Chip Select high */
71
  SPI_FLASH_CS_HIGH();
72
 
73
  /* SPI1 configuration */
74
  SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
75
  SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
76
  SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
77
  SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
78
  SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
79
  SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
80
  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
81
  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
82
  SPI_InitStructure.SPI_CRCPolynomial = 7;
83
  SPI_Init(SPI1, &SPI_InitStructure);
84
 
85
  /* Enable SPI1  */
86
  SPI_Cmd(SPI1, ENABLE);
87
}
88
 
89
/*******************************************************************************
90
* Function Name  : SPI_FLASH_SectorErase
91
* Description    : Erases the specified FLASH sector.
92
* Input          : SectorAddr: address of the sector to erase.
93
* Output         : None
94
* Return         : None
95
*******************************************************************************/
96
void SPI_FLASH_SectorErase(uint32_t SectorAddr)
97
{
98
  /* Send write enable instruction */
99
  SPI_FLASH_WriteEnable();
100
 
101
  /* Sector Erase */
102
  /* Select the FLASH: Chip Select low */
103
  SPI_FLASH_CS_LOW();
104
  /* Send Sector Erase instruction */
105
  SPI_FLASH_SendByte(SE);
106
  /* Send SectorAddr high nibble address byte */
107
  SPI_FLASH_SendByte((SectorAddr & 0xFF0000) >> 16);
108
  /* Send SectorAddr medium nibble address byte */
109
  SPI_FLASH_SendByte((SectorAddr & 0xFF00) >> 8);
110
  /* Send SectorAddr low nibble address byte */
111
  SPI_FLASH_SendByte(SectorAddr & 0xFF);
112
  /* Deselect the FLASH: Chip Select high */
113
  SPI_FLASH_CS_HIGH();
114
 
115
  /* Wait the end of Flash writing */
116
  SPI_FLASH_WaitForWriteEnd();
117
}
118
 
119
/*******************************************************************************
120
* Function Name  : SPI_FLASH_BulkErase
121
* Description    : Erases the entire FLASH.
122
* Input          : None
123
* Output         : None
124
* Return         : None
125
*******************************************************************************/
126
void SPI_FLASH_BulkErase(void)
127
{
128
  /* Send write enable instruction */
129
  SPI_FLASH_WriteEnable();
130
 
131
  /* Bulk Erase */
132
  /* Select the FLASH: Chip Select low */
133
  SPI_FLASH_CS_LOW();
134
  /* Send Bulk Erase instruction  */
135
  SPI_FLASH_SendByte(BE);
136
  /* Deselect the FLASH: Chip Select high */
137
  SPI_FLASH_CS_HIGH();
138
 
139
  /* Wait the end of Flash writing */
140
  SPI_FLASH_WaitForWriteEnd();
141
}
142
 
143
/*******************************************************************************
144
* Function Name  : SPI_FLASH_PageWrite
145
* Description    : Writes more than one byte to the FLASH with a single WRITE
146
*                  cycle(Page WRITE sequence). The number of byte can't exceed
147
*                  the FLASH page size.
148
* Input          : - pBuffer : pointer to the buffer  containing the data to be
149
*                    written to the FLASH.
150
*                  - WriteAddr : FLASH's internal address to write to.
151
*                  - NumByteToWrite : number of bytes to write to the FLASH,
152
*                    must be equal or less than "SPI_FLASH_PageSize" value.
153
* Output         : None
154
* Return         : None
155
*******************************************************************************/
156
void SPI_FLASH_PageWrite(uint8_t* pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite)
157
{
158
  /* Enable the write access to the FLASH */
159
  SPI_FLASH_WriteEnable();
160
 
161
  /* Select the FLASH: Chip Select low */
162
  SPI_FLASH_CS_LOW();
163
  /* Send "Write to Memory " instruction */
164
  SPI_FLASH_SendByte(WRITE);
165
  /* Send WriteAddr high nibble address byte to write to */
166
  SPI_FLASH_SendByte((WriteAddr & 0xFF0000) >> 16);
167
  /* Send WriteAddr medium nibble address byte to write to */
168
  SPI_FLASH_SendByte((WriteAddr & 0xFF00) >> 8);
169
  /* Send WriteAddr low nibble address byte to write to */
170
  SPI_FLASH_SendByte(WriteAddr & 0xFF);
171
 
172
  /* while there is data to be written on the FLASH */
173
  while (NumByteToWrite--)
174
  {
175
    /* Send the current byte */
176
    SPI_FLASH_SendByte(*pBuffer);
177
    /* Point on the next byte to be written */
178
    pBuffer++;
179
  }
180
 
181
  /* Deselect the FLASH: Chip Select high */
182
  SPI_FLASH_CS_HIGH();
183
 
184
  /* Wait the end of Flash writing */
185
  SPI_FLASH_WaitForWriteEnd();
186
}
187
 
188
/*******************************************************************************
189
* Function Name  : SPI_FLASH_BufferWrite
190
* Description    : Writes block of data to the FLASH. In this function, the
191
*                  number of WRITE cycles are reduced, using Page WRITE sequence.
192
* Input          : - pBuffer : pointer to the buffer  containing the data to be
193
*                    written to the FLASH.
194
*                  - WriteAddr : FLASH's internal address to write to.
195
*                  - NumByteToWrite : number of bytes to write to the FLASH.
196
* Output         : None
197
* Return         : None
198
*******************************************************************************/
199
void SPI_FLASH_BufferWrite(uint8_t* pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite)
200
{
201
  uint8_t NumOfPage = 0, NumOfSingle = 0, Addr = 0, count = 0, temp = 0;
202
 
203
  Addr = WriteAddr % SPI_FLASH_PageSize;
204
  count = SPI_FLASH_PageSize - Addr;
205
  NumOfPage =  NumByteToWrite / SPI_FLASH_PageSize;
206
  NumOfSingle = NumByteToWrite % SPI_FLASH_PageSize;
207
 
208
  if (Addr == 0) /* WriteAddr is SPI_FLASH_PageSize aligned  */
209
  {
210
    if (NumOfPage == 0) /* NumByteToWrite < SPI_FLASH_PageSize */
211
    {
212
      SPI_FLASH_PageWrite(pBuffer, WriteAddr, NumByteToWrite);
213
    }
214
    else /* NumByteToWrite > SPI_FLASH_PageSize */
215
    {
216
      while (NumOfPage--)
217
      {
218
        SPI_FLASH_PageWrite(pBuffer, WriteAddr, SPI_FLASH_PageSize);
219
        WriteAddr +=  SPI_FLASH_PageSize;
220
        pBuffer += SPI_FLASH_PageSize;
221
      }
222
 
223
      SPI_FLASH_PageWrite(pBuffer, WriteAddr, NumOfSingle);
224
    }
225
  }
226
  else /* WriteAddr is not SPI_FLASH_PageSize aligned  */
227
  {
228
    if (NumOfPage == 0) /* NumByteToWrite < SPI_FLASH_PageSize */
229
    {
230
      if (NumOfSingle > count) /* (NumByteToWrite + WriteAddr) > SPI_FLASH_PageSize */
231
      {
232
        temp = NumOfSingle - count;
233
 
234
        SPI_FLASH_PageWrite(pBuffer, WriteAddr, count);
235
        WriteAddr +=  count;
236
        pBuffer += count;
237
 
238
        SPI_FLASH_PageWrite(pBuffer, WriteAddr, temp);
239
      }
240
      else
241
      {
242
        SPI_FLASH_PageWrite(pBuffer, WriteAddr, NumByteToWrite);
243
      }
244
    }
245
    else /* NumByteToWrite > SPI_FLASH_PageSize */
246
    {
247
      NumByteToWrite -= count;
248
      NumOfPage =  NumByteToWrite / SPI_FLASH_PageSize;
249
      NumOfSingle = NumByteToWrite % SPI_FLASH_PageSize;
250
 
251
      SPI_FLASH_PageWrite(pBuffer, WriteAddr, count);
252
      WriteAddr +=  count;
253
      pBuffer += count;
254
 
255
      while (NumOfPage--)
256
      {
257
        SPI_FLASH_PageWrite(pBuffer, WriteAddr, SPI_FLASH_PageSize);
258
        WriteAddr +=  SPI_FLASH_PageSize;
259
        pBuffer += SPI_FLASH_PageSize;
260
      }
261
 
262
      if (NumOfSingle != 0)
263
      {
264
        SPI_FLASH_PageWrite(pBuffer, WriteAddr, NumOfSingle);
265
      }
266
    }
267
  }
268
}
269
 
270
/*******************************************************************************
271
* Function Name  : SPI_FLASH_BufferRead
272
* Description    : Reads a block of data from the FLASH.
273
* Input          : - pBuffer : pointer to the buffer that receives the data read
274
*                    from the FLASH.
275
*                  - ReadAddr : FLASH's internal address to read from.
276
*                  - NumByteToRead : number of bytes to read from the FLASH.
277
* Output         : None
278
* Return         : None
279
*******************************************************************************/
280
void SPI_FLASH_BufferRead(uint8_t* pBuffer, uint32_t ReadAddr, uint16_t NumByteToRead)
281
{
282
  /* Select the FLASH: Chip Select low */
283
  SPI_FLASH_CS_LOW();
284
 
285
  /* Send "Read from Memory " instruction */
286
  SPI_FLASH_SendByte(READ);
287
 
288
  /* Send ReadAddr high nibble address byte to read from */
289
  SPI_FLASH_SendByte((ReadAddr & 0xFF0000) >> 16);
290
  /* Send ReadAddr medium nibble address byte to read from */
291
  SPI_FLASH_SendByte((ReadAddr& 0xFF00) >> 8);
292
  /* Send ReadAddr low nibble address byte to read from */
293
  SPI_FLASH_SendByte(ReadAddr & 0xFF);
294
 
295
  while (NumByteToRead--) /* while there is data to be read */
296
  {
297
    /* Read a byte from the FLASH */
298
    *pBuffer = SPI_FLASH_SendByte(Dummy_Byte);
299
    /* Point to the next location where the byte read will be saved */
300
    pBuffer++;
301
  }
302
 
303
  /* Deselect the FLASH: Chip Select high */
304
  SPI_FLASH_CS_HIGH();
305
}
306
 
307
/*******************************************************************************
308
* Function Name  : SPI_FLASH_ReadID
309
* Description    : Reads FLASH identification.
310
* Input          : None
311
* Output         : None
312
* Return         : FLASH identification
313
*******************************************************************************/
314
uint32_t SPI_FLASH_ReadID(void)
315
{
316
  uint32_t Temp = 0, Temp0 = 0, Temp1 = 0, Temp2 = 0;
317
 
318
  /* Select the FLASH: Chip Select low */
319
  SPI_FLASH_CS_LOW();
320
 
321
  /* Send "RDID " instruction */
322
  SPI_FLASH_SendByte(0x9F);
323
 
324
  /* Read a byte from the FLASH */
325
  Temp0 = SPI_FLASH_SendByte(Dummy_Byte);
326
 
327
  /* Read a byte from the FLASH */
328
  Temp1 = SPI_FLASH_SendByte(Dummy_Byte);
329
 
330
  /* Read a byte from the FLASH */
331
  Temp2 = SPI_FLASH_SendByte(Dummy_Byte);
332
 
333
  /* Deselect the FLASH: Chip Select high */
334
  SPI_FLASH_CS_HIGH();
335
 
336
  Temp = (Temp0 << 16) | (Temp1 << 8) | Temp2;
337
 
338
  return Temp;
339
}
340
 
341
/*******************************************************************************
342
* Function Name  : SPI_FLASH_StartReadSequence
343
* Description    : Initiates a read data byte (READ) sequence from the Flash.
344
*                  This is done by driving the /CS line low to select the device,
345
*                  then the READ instruction is transmitted followed by 3 bytes
346
*                  address. This function exit and keep the /CS line low, so the
347
*                  Flash still being selected. With this technique the whole
348
*                  content of the Flash is read with a single READ instruction.
349
* Input          : - ReadAddr : FLASH's internal address to read from.
350
* Output         : None
351
* Return         : None
352
*******************************************************************************/
353
void SPI_FLASH_StartReadSequence(uint32_t ReadAddr)
354
{
355
  /* Select the FLASH: Chip Select low */
356
  SPI_FLASH_CS_LOW();
357
 
358
  /* Send "Read from Memory " instruction */
359
  SPI_FLASH_SendByte(READ);
360
 
361
  /* Send the 24-bit address of the address to read from -----------------------*/
362
  /* Send ReadAddr high nibble address byte */
363
  SPI_FLASH_SendByte((ReadAddr & 0xFF0000) >> 16);
364
  /* Send ReadAddr medium nibble address byte */
365
  SPI_FLASH_SendByte((ReadAddr& 0xFF00) >> 8);
366
  /* Send ReadAddr low nibble address byte */
367
  SPI_FLASH_SendByte(ReadAddr & 0xFF);
368
}
369
 
370
/*******************************************************************************
371
* Function Name  : SPI_FLASH_ReadByte
372
* Description    : Reads a byte from the SPI Flash.
373
*                  This function must be used only if the Start_Read_Sequence
374
*                  function has been previously called.
375
* Input          : None
376
* Output         : None
377
* Return         : Byte Read from the SPI Flash.
378
*******************************************************************************/
379
uint8_t SPI_FLASH_ReadByte(void)
380
{
381
  return (SPI_FLASH_SendByte(Dummy_Byte));
382
}
383
 
384
/*******************************************************************************
385
* Function Name  : SPI_FLASH_SendByte
386
* Description    : Sends a byte through the SPI interface and return the byte
387
*                  received from the SPI bus.
388
* Input          : byte : byte to send.
389
* Output         : None
390
* Return         : The value of the received byte.
391
*******************************************************************************/
392
uint8_t SPI_FLASH_SendByte(uint8_t byte)
393
{
394
  /* Loop while DR register in not emplty */
395
  while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
396
 
397
  /* Send byte through the SPI1 peripheral */
398
  SPI_I2S_SendData(SPI1, byte);
399
 
400
  /* Wait to receive a byte */
401
  while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);
402
 
403
  /* Return the byte read from the SPI bus */
404
  return SPI_I2S_ReceiveData(SPI1);
405
}
406
 
407
/*******************************************************************************
408
* Function Name  : SPI_FLASH_SendHalfWord
409
* Description    : Sends a Half Word through the SPI interface and return the
410
*                  Half Word received from the SPI bus.
411
* Input          : Half Word : Half Word to send.
412
* Output         : None
413
* Return         : The value of the received Half Word.
414
*******************************************************************************/
415
uint16_t SPI_FLASH_SendHalfWord(uint16_t HalfWord)
416
{
417
  /* Loop while DR register in not emplty */
418
  while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
419
 
420
  /* Send Half Word through the SPI1 peripheral */
421
  SPI_I2S_SendData(SPI1, HalfWord);
422
 
423
  /* Wait to receive a Half Word */
424
  while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);
425
 
426
  /* Return the Half Word read from the SPI bus */
427
  return SPI_I2S_ReceiveData(SPI1);
428
}
429
 
430
/*******************************************************************************
431
* Function Name  : SPI_FLASH_WriteEnable
432
* Description    : Enables the write access to the FLASH.
433
* Input          : None
434
* Output         : None
435
* Return         : None
436
*******************************************************************************/
437
void SPI_FLASH_WriteEnable(void)
438
{
439
  /* Select the FLASH: Chip Select low */
440
  SPI_FLASH_CS_LOW();
441
 
442
  /* Send "Write Enable" instruction */
443
  SPI_FLASH_SendByte(WREN);
444
 
445
  /* Deselect the FLASH: Chip Select high */
446
  SPI_FLASH_CS_HIGH();
447
}
448
 
449
/*******************************************************************************
450
* Function Name  : SPI_FLASH_WaitForWriteEnd
451
* Description    : Polls the status of the Write In Progress (WIP) flag in the
452
*                  FLASH's status  register  and  loop  until write  opertaion
453
*                  has completed.
454
* Input          : None
455
* Output         : None
456
* Return         : None
457
*******************************************************************************/
458
void SPI_FLASH_WaitForWriteEnd(void)
459
{
460
  uint8_t FLASH_Status = 0;
461
 
462
  /* Select the FLASH: Chip Select low */
463
  SPI_FLASH_CS_LOW();
464
 
465
  /* Send "Read Status Register" instruction */
466
  SPI_FLASH_SendByte(RDSR);
467
 
468
  /* Loop as long as the memory is busy with a write cycle */
469
  do
470
  {
471
    /* Send a dummy byte to generate the clock needed by the FLASH
472
    and put the value of the status register in FLASH_Status variable */
473
    FLASH_Status = SPI_FLASH_SendByte(Dummy_Byte);
474
 
475
  }
476
  while ((FLASH_Status & WIP_Flag) == SET); /* Write in progress */
477
 
478
  /* Deselect the FLASH: Chip Select high */
479
  SPI_FLASH_CS_HIGH();
480
}
481
 
482
/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.