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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [freertos-6.1.1/] [Demo/] [CORTEX_STM32F103_Keil/] [spi_flash.c] - Blame information for rev 728

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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