Added support for v4.2 boards
[SCSI2SD.git] / software / SCSI2SD / v4 / SCSI2SD.cydsn / Generated_Source / PSoC5 / CyFlash.c
1 /*******************************************************************************
2 * File Name: CyFlash.c
3 * Version 4.0
4 *
5 *  Description:
6 *   Provides an API for the FLASH/EEPROM.
7 *
8 *  Note:
9 *   This code is endian agnostic.
10 *
11 *  Note:
12 *   Documentation of the API's in this file is located in the
13 *   System Reference Guide provided with PSoC Creator.
14 *
15 ********************************************************************************
16 * Copyright 2008-2013, Cypress Semiconductor Corporation. All rights reserved.
17 * You may use this file only in accordance with the license, terms, conditions,
18 * disclaimers, and limitations in the end user license agreement accompanying
19 * the software package with which this file was provided.
20 *******************************************************************************/
21
22 #include "CyFlash.h"
23
24
25 /*******************************************************************************
26 * Holds die temperature, updated by CySetTemp(). Used for flash writting.
27 * The first byte is the sign of the temperature (0 = negative, 1 = positive).
28 * The second byte is the magnitude.
29 *******************************************************************************/
30 uint8 dieTemperature[CY_FLASH_DIE_TEMP_DATA_SIZE];
31
32 #if(CYDEV_ECC_ENABLE == 0)
33     static uint8 * rowBuffer = 0;
34 #endif  /* (CYDEV_ECC_ENABLE == 0) */
35
36
37 static cystatus CySetTempInt(void);
38
39
40 /*******************************************************************************
41 * Function Name: CyFlash_Start
42 ********************************************************************************
43 *
44 * Summary:
45 *  Enable the Flash.
46 *
47 * Parameters:
48 *  None
49 *
50 * Return:
51 *  None
52 *
53 *******************************************************************************/
54 void CyFlash_Start(void) 
55 {
56     /* Active Power Mode */
57     *CY_FLASH_PM_ACT_EEFLASH_PTR |= CY_FLASH_PM_FLASH_MASK;
58
59     /* Standby Power Mode */
60     *CY_FLASH_PM_ALTACT_EEFLASH_PTR |= CY_FLASH_PM_FLASH_MASK;
61
62     CyDelayUs(CY_FLASH_EE_STARTUP_DELAY);
63 }
64
65
66 /*******************************************************************************
67 * Function Name: CyFlash_Stop
68 ********************************************************************************
69 *
70 * Summary:
71 *  Disable the Flash.
72 *
73 * Parameters:
74 *  None
75 *
76 * Return:
77 *  None
78 *
79 * Side Effects:
80 *  This setting is ignored as long as the CPU is currently running.  This will
81 *  only take effect when the CPU is later disabled.
82 *
83 *******************************************************************************/
84 void CyFlash_Stop(void) 
85 {
86     /* Active Power Mode */
87     *CY_FLASH_PM_ACT_EEFLASH_PTR &= ((uint8)(~CY_FLASH_PM_FLASH_MASK));
88
89     /* Standby Power Mode */
90     *CY_FLASH_PM_ALTACT_EEFLASH_PTR &= ((uint8)(~CY_FLASH_PM_FLASH_MASK));
91 }
92
93
94 /*******************************************************************************
95 * Function Name: CySetTempInt
96 ********************************************************************************
97 *
98 * Summary:
99 *  Sends a command to the SPC to read the die temperature. Sets a global value
100 *  used by the Write functions. This function must be called once before
101 *  executing a series of Flash writing functions.
102 *
103 * Parameters:
104 *  None
105 *
106 * Return:
107 *  status:
108 *   CYRET_SUCCESS - if successful
109 *   CYRET_LOCKED  - if Flash writing already in use
110 *   CYRET_UNKNOWN - if there was an SPC error
111 *
112 *******************************************************************************/
113 static cystatus CySetTempInt(void) 
114 {
115     cystatus status;
116
117     /* Make sure SPC is powered */
118     CySpcStart();
119
120     /* Plan for failure. */
121     status = CYRET_UNKNOWN;
122
123     if(CySpcLock() == CYRET_SUCCESS)
124     {
125         /* Write the command. */
126         if(CYRET_STARTED == CySpcGetTemp(CY_TEMP_NUMBER_OF_SAMPLES))
127         {
128             do
129             {
130                 if(CySpcReadData(dieTemperature, CY_FLASH_DIE_TEMP_DATA_SIZE) == CY_FLASH_DIE_TEMP_DATA_SIZE)
131                 {
132                     status = CYRET_SUCCESS;
133
134                     while(CY_SPC_BUSY)
135                     {
136                         /* Spin until idle. */
137                         CyDelayUs(1u);
138                     }
139                     break;
140                 }
141
142             } while(CY_SPC_BUSY);
143         }
144
145         CySpcUnlock();
146     }
147     else
148     {
149         status = CYRET_LOCKED;
150     }
151
152     return (status);
153 }
154
155
156 /*******************************************************************************
157 * Function Name: CySetTemp
158 ********************************************************************************
159 *
160 * Summary:
161 *  This is a wraparound for CySetTempInt(). It is used to return second
162 *  successful read of temperature value.
163 *
164 * Parameters:
165 *  None
166 *
167 * Return:
168 *  status:
169 *   CYRET_SUCCESS if successful.
170 *   CYRET_LOCKED  if Flash writing already in use
171 *   CYRET_UNKNOWN if there was an SPC error.
172 *
173 *  uint8 dieTemperature[2]:
174 *   Holds die temperature for the flash writting algorithm. The first byte is
175 *   the sign of the temperature (0 = negative, 1 = positive). The second byte is
176 *   the magnitude.
177 *
178 *******************************************************************************/
179 cystatus CySetTemp(void) 
180 {
181     cystatus status = CySetTempInt();
182
183     if(status == CYRET_SUCCESS)
184     {
185         status = CySetTempInt();
186     }
187
188     return (status);
189 }
190
191
192 /*******************************************************************************
193 * Function Name: CySetFlashEEBuffer
194 ********************************************************************************
195 *
196 * Summary:
197 *  Sets the user supplied temporary buffer to store SPC data while performing
198 *  flash and EEPROM commands. This buffer is only necessary when Flash ECC is
199 *  disabled.
200 *
201 * Parameters:
202 *  buffer:
203 *   Address of block of memory to store temporary memory. The size of the block
204 *   of memory is CYDEV_FLS_ROW_SIZE + CYDEV_ECC_ROW_SIZE.
205 *
206 * Return:
207 *  status:
208 *   CYRET_SUCCESS if successful.
209 *   CYRET_BAD_PARAM if the buffer is NULL
210 *
211 *******************************************************************************/
212 cystatus CySetFlashEEBuffer(uint8 * buffer) 
213 {
214     cystatus status = CYRET_SUCCESS;
215
216     CySpcStart();
217
218     #if(CYDEV_ECC_ENABLE == 0)
219
220         if(NULL == buffer)
221         {
222             status = CYRET_BAD_PARAM;
223         }
224         else if(CySpcLock() != CYRET_SUCCESS)
225         {
226             status = CYRET_LOCKED;
227         }
228         else
229         {
230             rowBuffer = buffer;
231             CySpcUnlock();
232         }
233
234     #else
235
236         /* To supress the warning */
237         buffer = buffer;
238
239     #endif  /* (CYDEV_ECC_ENABLE == 0u) */
240
241     return(status);
242 }
243
244
245 #if(CYDEV_ECC_ENABLE == 1)
246
247     /*******************************************************************************
248     * Function Name: CyWriteRowData
249     ********************************************************************************
250     *
251     * Summary:
252     *  Sends a command to the SPC to load and program a row of data in
253     *  Flash or EEPROM.
254     *
255     * Parameters:
256     *  arrayID:    ID of the array to write.
257     *   The type of write, Flash or EEPROM, is determined from the array ID.
258     *   The arrays in the part are sequential starting at the first ID for the
259     *   specific memory type. The array ID for the Flash memory lasts from 0x00 to
260     *   0x3F and for the EEPROM memory it lasts from 0x40 to 0x7F.
261     *  rowAddress: rowAddress of flash row to program.
262     *  rowData:    Array of bytes to write.
263     *
264     * Return:
265     *  status:
266     *   CYRET_SUCCESS if successful.
267     *   CYRET_LOCKED if the SPC is already in use.
268     *   CYRET_CANCELED if command not accepted
269     *   CYRET_UNKNOWN if there was an SPC error.
270     *
271     *******************************************************************************/
272     cystatus CyWriteRowData(uint8 arrayId, uint16 rowAddress, const uint8 * rowData) 
273     {
274         uint16 rowSize;
275         cystatus status;
276
277         rowSize = (arrayId > CY_SPC_LAST_FLASH_ARRAYID) ? CYDEV_EEPROM_ROW_SIZE : CYDEV_FLS_ROW_SIZE;
278         status = CyWriteRowFull(arrayId, rowAddress, rowData, rowSize);
279
280         return(status);
281     }
282
283 #else
284
285     /*******************************************************************************
286     * Function Name: CyWriteRowData
287     ********************************************************************************
288     *
289     * Summary:
290     *   Sends a command to the SPC to load and program a row of data in
291     *   Flash or EEPROM.
292     *
293     * Parameters:
294     *  arrayID      : ID of the array to write.
295     *   The type of write, Flash or EEPROM, is determined from the array ID.
296     *   The arrays in the part are sequential starting at the first ID for the
297     *   specific memory type. The array ID for the Flash memory lasts from 0x00 to
298     *   0x3F and for the EEPROM memory it lasts from 0x40 to 0x7F.
299     *  rowAddress   : rowAddress of flash row to program.
300     *  rowData      : Array of bytes to write.
301     *
302     * Return:
303     *  status:
304     *   CYRET_SUCCESS if successful.
305     *   CYRET_LOCKED if the SPC is already in use.
306     *   CYRET_CANCELED if command not accepted
307     *   CYRET_UNKNOWN if there was an SPC error.
308     *
309     *******************************************************************************/
310     cystatus CyWriteRowData(uint8 arrayId, uint16 rowAddress, const uint8 * rowData) 
311     {
312         uint8 i;
313         uint32 offset;
314         uint16 rowSize;
315         cystatus status;
316
317         /* Check whether rowBuffer pointer has been initialized by CySetFlashEEBuffer() */
318         if(NULL != rowBuffer)
319         {
320             if(arrayId > CY_SPC_LAST_FLASH_ARRAYID)
321             {
322                 rowSize = CYDEV_EEPROM_ROW_SIZE;
323             }
324             else
325             {
326                 rowSize = CYDEV_FLS_ROW_SIZE + CYDEV_ECC_ROW_SIZE;
327
328                 /* Save the ECC area. */
329                 offset = CYDEV_ECC_BASE +
330                         ((uint32)arrayId * CYDEV_ECC_SECTOR_SIZE) +
331                         ((uint32)rowAddress * CYDEV_ECC_ROW_SIZE);
332
333                 for(i = 0u; i < CYDEV_ECC_ROW_SIZE; i++)
334                 {
335                     *(rowBuffer + CYDEV_FLS_ROW_SIZE + i) = CY_GET_XTND_REG8((void CYFAR *)(offset + i));
336                 }
337             }
338
339             /* Copy the rowdata to the temporary buffer. */
340         #if(CY_PSOC3)
341             (void) memcpy((void *) rowBuffer, (void *)((uint32) rowData), (int16) CYDEV_FLS_ROW_SIZE);
342         #else
343             (void) memcpy((void *) rowBuffer, (const void *) rowData, CYDEV_FLS_ROW_SIZE);
344         #endif  /* (CY_PSOC3) */
345
346             status = CyWriteRowFull(arrayId, rowAddress, rowBuffer, rowSize);
347         }
348         else
349         {
350             status = CYRET_UNKNOWN;
351         }
352
353         return(status);
354     }
355
356 #endif /* (CYDEV_ECC_ENABLE == 0u) */
357
358
359 #if ((CYDEV_ECC_ENABLE == 0u) && (CYDEV_CONFIGURATION_ECC == 0u))
360
361     /*******************************************************************************
362     * Function Name: CyWriteRowConfig
363     ********************************************************************************
364     *
365     * Summary:
366     *  Sends a command to the SPC to load and program a row of config data in flash.
367     *  This function is only valid for Flash array IDs (not for EEPROM).
368     *
369     * Parameters:
370     *  arrayId:      ID of the array to write
371     *   The arrays in the part are sequential starting at the first ID for the
372     *   specific memory type. The array ID for the Flash memory lasts
373     *   from 0x00 to 0x3F.
374     *  rowAddress:   Address of the sector to erase.
375     *  rowECC:       Array of bytes to write.
376     *
377     * Return:
378     *  status:
379     *   CYRET_SUCCESS if successful.
380     *   CYRET_LOCKED if the SPC is already in use.
381     *   CYRET_CANCELED if command not accepted
382     *   CYRET_UNKNOWN if there was an SPC error.
383     *
384     *******************************************************************************/
385     cystatus CyWriteRowConfig(uint8 arrayId, uint16 rowAddress, const uint8 * rowECC)\
386     
387     {
388         uint32 offset;
389         uint16 i;
390         cystatus status;
391
392         /* Check whether rowBuffer pointer has been initialized by CySetFlashEEBuffer() */
393         if(NULL != rowBuffer)
394         {
395             /* Read the existing flash data. */
396             offset = ((uint32)arrayId * CYDEV_FLS_SECTOR_SIZE) +
397                      ((uint32)rowAddress * CYDEV_FLS_ROW_SIZE);
398
399             #if (CYDEV_FLS_BASE != 0u)
400                 offset += CYDEV_FLS_BASE;
401             #endif  /* (CYDEV_FLS_BASE != 0u) */
402
403             for (i = 0u; i < CYDEV_FLS_ROW_SIZE; i++)
404             {
405                 rowBuffer[i] = CY_GET_XTND_REG8((void CYFAR *)(offset + i));
406             }
407
408             #if(CY_PSOC3)
409                 (void) memcpy((void *)&rowBuffer[CYDEV_FLS_ROW_SIZE],
410                               (void *)(uint32)rowECC,
411                               (int16)CYDEV_ECC_ROW_SIZE);
412             #else
413                 (void) memcpy((void *)&rowBuffer[CYDEV_FLS_ROW_SIZE],
414                               (const void *)rowECC,
415                               CYDEV_ECC_ROW_SIZE);
416             #endif  /* (CY_PSOC3) */
417
418             status = CyWriteRowFull(arrayId, rowAddress, rowBuffer, CYDEV_FLS_ROW_SIZE + CYDEV_ECC_ROW_SIZE);
419         }
420         else
421         {
422             status = CYRET_UNKNOWN;
423         }
424
425         return (status);
426     }
427
428 #endif  /* ((CYDEV_ECC_ENABLE == 0u) && (CYDEV_CONFIGURATION_ECC == 0u)) */
429
430
431
432 /*******************************************************************************
433 * Function Name: CyWriteRowFull
434 ********************************************************************************
435 * Summary:
436 *  Sends a command to the SPC to load and program a row of data in flash.
437 *  rowData array is expected to contain Flash and ECC data if needed.
438 *
439 * Parameters:
440 *  arrayId:    FLASH or EEPROM array id.
441 *  rowData:    Pointer to a row of data to write.
442 *  rowNumber:  Zero based number of the row.
443 *  rowSize:    Size of the row.
444 *
445 * Return:
446 *  CYRET_SUCCESS if successful.
447 *  CYRET_LOCKED if the SPC is already in use.
448 *  CYRET_CANCELED if command not accepted
449 *  CYRET_UNKNOWN if there was an SPC error.
450 *
451 *******************************************************************************/
452 cystatus CyWriteRowFull(uint8 arrayId, uint16 rowNumber, const uint8* rowData, uint16 rowSize) \
453         
454 {
455     cystatus status;
456
457     if(CySpcLock() == CYRET_SUCCESS)
458     {
459         /* Load row data into SPC internal latch */
460         status = CySpcLoadRow(arrayId, rowData, rowSize);
461
462         if(CYRET_STARTED == status)
463         {
464             while(CY_SPC_BUSY)
465             {
466                 /* Wait for SPC to finish and get SPC status */
467                 CyDelayUs(1u);
468             }
469
470             /* Hide SPC status */
471             if(CY_SPC_STATUS_SUCCESS == CY_SPC_READ_STATUS)
472             {
473                 status = CYRET_SUCCESS;
474             }
475             else
476             {
477                 status = CYRET_UNKNOWN;
478             }
479
480             if(CYRET_SUCCESS == status)
481             {
482                 /* Erase and program flash with the data from SPC interval latch */
483                 status = CySpcWriteRow(arrayId, rowNumber, dieTemperature[0u], dieTemperature[1u]);
484
485                 if(CYRET_STARTED == status)
486                 {
487                     while(CY_SPC_BUSY)
488                     {
489                         /* Wait for SPC to finish and get SPC status */
490                         CyDelayUs(1u);
491                     }
492
493                     /* Hide SPC status */
494                     if(CY_SPC_STATUS_SUCCESS == CY_SPC_READ_STATUS)
495                     {
496                         status = CYRET_SUCCESS;
497                     }
498                     else
499                     {
500                         status = CYRET_UNKNOWN;
501                     }
502                 }
503             }
504
505         }
506
507         CySpcUnlock();
508     }
509     else
510     {
511         status = CYRET_LOCKED;
512     }
513
514     return(status);
515 }
516
517
518 /*******************************************************************************
519 * Function Name: CyFlash_SetWaitCycles
520 ********************************************************************************
521 *
522 * Summary:
523 *  Sets the number of clock cycles the cache will wait before it samples data
524 *  coming back from Flash. This function must be called before increasing CPU
525 *  clock frequency. It can optionally be called after lowering CPU clock
526 *  frequency in order to improve CPU performance.
527 *
528 * Parameters:
529 *  uint8 freq:
530 *   Frequency of operation in Megahertz.
531 *
532 * Return:
533 *  None
534 *
535 *******************************************************************************/
536 void CyFlash_SetWaitCycles(uint8 freq) 
537 {
538     uint8 interruptState;
539
540     /* Save current global interrupt enable and disable it */
541     interruptState = CyEnterCriticalSection();
542
543     /***************************************************************************
544     * The number of clock cycles the cache will wait before it samples data
545     * coming back from Flash must be equal or greater to to the CPU frequency
546     * outlined in clock cycles.
547     ***************************************************************************/
548
549     #if (CY_PSOC3)
550
551         if (freq <= 22u)
552         {
553             *CY_FLASH_CONTROL_PTR = ((*CY_FLASH_CONTROL_PTR & ((uint8)(~CY_FLASH_CYCLES_MASK))) |
554                 ((uint8)(CY_FLASH_LESSER_OR_EQUAL_22MHz << CY_FLASH_CYCLES_MASK_SHIFT)));
555         }
556         else if (freq <= 44u)
557         {
558             *CY_FLASH_CONTROL_PTR = ((*CY_FLASH_CONTROL_PTR & ((uint8)(~CY_FLASH_CYCLES_MASK))) |
559                 ((uint8)(CY_FLASH_LESSER_OR_EQUAL_44MHz << CY_FLASH_CYCLES_MASK_SHIFT)));
560         }
561         else
562         {
563             *CY_FLASH_CONTROL_PTR = ((*CY_FLASH_CONTROL_PTR & ((uint8)(~CY_FLASH_CYCLES_MASK))) |
564                 ((uint8)(CY_FLASH_GREATER_44MHz << CY_FLASH_CYCLES_MASK_SHIFT)));
565         }
566
567     #endif  /* (CY_PSOC3) */
568
569
570     #if (CY_PSOC5)
571
572         if (freq <= 16u)
573         {
574             *CY_FLASH_CONTROL_PTR = ((*CY_FLASH_CONTROL_PTR & ((uint8)(~CY_FLASH_CYCLES_MASK))) |
575                 ((uint8)(CY_FLASH_LESSER_OR_EQUAL_16MHz << CY_FLASH_CYCLES_MASK_SHIFT)));
576         }
577         else if (freq <= 33u)
578         {
579             *CY_FLASH_CONTROL_PTR = ((*CY_FLASH_CONTROL_PTR & ((uint8)(~CY_FLASH_CYCLES_MASK))) |
580                 ((uint8)(CY_FLASH_LESSER_OR_EQUAL_33MHz << CY_FLASH_CYCLES_MASK_SHIFT)));
581         }
582         else if (freq <= 50u)
583         {
584             *CY_FLASH_CONTROL_PTR = ((*CY_FLASH_CONTROL_PTR & ((uint8)(~CY_FLASH_CYCLES_MASK))) |
585                 ((uint8)(CY_FLASH_LESSER_OR_EQUAL_50MHz << CY_FLASH_CYCLES_MASK_SHIFT)));
586         }
587         else
588         {
589             *CY_FLASH_CONTROL_PTR = ((*CY_FLASH_CONTROL_PTR & ((uint8)(~CY_FLASH_CYCLES_MASK))) |
590                 ((uint8)(CY_FLASH_GREATER_51MHz << CY_FLASH_CYCLES_MASK_SHIFT)));
591         }
592
593     #endif  /* (CY_PSOC5) */
594
595     /* Restore global interrupt enable state */
596     CyExitCriticalSection(interruptState);
597 }
598
599
600 /*******************************************************************************
601 * Function Name: CyEEPROM_Start
602 ********************************************************************************
603 *
604 * Summary:
605 *  Enable the EEPROM.
606 *
607 * Parameters:
608 *  None
609 *
610 * Return:
611 *  None
612 *
613 *******************************************************************************/
614 void CyEEPROM_Start(void) 
615 {
616     /* Active Power Mode */
617     *CY_FLASH_PM_ACT_EEFLASH_PTR |= CY_FLASH_PM_EE_MASK;
618
619     /* Standby Power Mode */
620     *CY_FLASH_PM_ALTACT_EEFLASH_PTR |= CY_FLASH_PM_EE_MASK;
621 }
622
623
624 /*******************************************************************************
625 * Function Name: CyEEPROM_Stop
626 ********************************************************************************
627 *
628 * Summary:
629 *  Disable the EEPROM.
630 *
631 * Parameters:
632 *  None
633 *
634 * Return:
635 *  None
636 *
637 *******************************************************************************/
638 void CyEEPROM_Stop (void) 
639 {
640     /* Active Power Mode */
641     *CY_FLASH_PM_ACT_EEFLASH_PTR &= ((uint8)(~CY_FLASH_PM_EE_MASK));
642
643     /* Standby Power Mode */
644     *CY_FLASH_PM_ALTACT_EEFLASH_PTR &= ((uint8)(~CY_FLASH_PM_EE_MASK));
645 }
646
647
648 /*******************************************************************************
649 * Function Name: CyEEPROM_ReadReserve
650 ********************************************************************************
651 *
652 * Summary:
653 *  Request access to the EEPROM for reading and wait until access is available.
654 *
655 * Parameters:
656 *  None
657 *
658 * Return:
659 *  None
660 *
661 *******************************************************************************/
662 void CyEEPROM_ReadReserve(void) 
663 {
664     /* Make a request for PHUB to have access */
665     *CY_FLASH_EE_SCR_PTR |= CY_FLASH_EE_SCR_AHB_EE_REQ;
666
667     while (0u == (*CY_FLASH_EE_SCR_PTR & CY_FLASH_EE_SCR_AHB_EE_ACK))
668     {
669         /* Wait for acknowledgement from PHUB */
670     }
671 }
672
673
674 /*******************************************************************************
675 * Function Name: CyEEPROM_ReadRelease
676 ********************************************************************************
677 *
678 * Summary:
679 *  Release the read reservation of the EEPROM.
680 *
681 * Parameters:
682 *  None
683 *
684 * Return:
685 *  None
686 *
687 *******************************************************************************/
688 void CyEEPROM_ReadRelease(void) 
689 {
690     *CY_FLASH_EE_SCR_PTR |= 0x00u;
691 }
692
693
694 /* [] END OF FILE */