1 /*************************************************************************
2 *
3 * File name : FlashPrg.c
4 * Description : Cypress FM4 internal flashloader
5 *
6 * History :
7 * 1. Date : 9, 2018
8 * Author : Kevin Zhou
9 * Description : Adapt for S6E2H series
10 *
11 * $Revision: 0 $
12 **************************************************************************/
13 #include "FlashOS.H" // FlashOS Structures
14
15 #include "s6e2hgxg.h"
16
17
18 typedef enum {IDLE, ERASE, WRITE} status;
19
20 #define flash_unit u16
21 #define flash_ptr volatile flash_unit *
22
23 //Flash commands
24 #define READ_RESET 0xF0
25 #define MASS_ERASE 0x10
26 #define SECTOR_ERASE 0x30
27 #define FLASH_WRITE 0xA0
28 #define SECTOR_ERASE_SUSPEND 0xB0
29 #define READ 0xF0
30 #define DATA1 0x55 //General command signature
31 #define DATA2 0x80 //General command signature
32 #define DATA3 0xAA //General command signature
33
34 //Magic flash addresses
35 #define ADDRESS1 0xAA8
36 #define ADDRESS2 0x554
37
38 //Commands use 16bit access
39 #define SET_COMMAND(data, address) *((flash_ptr)address) = (flash_unit)data
40
41 //Hardware sequence flags
42 #define DPOL 0x80
43 #define TOGG 0x40
44 #define TLOV 0x20
45 #define SETI 0x08
46 #define TOGG2 0x04
47
48 #define PROTECT_OFFSET 0x400000
49 #define CR_TRIM_OFFSET 0x402000
50
51 static void FlashCleanup(flash_ptr flash_halfword) {
52 *flash_halfword = READ_RESET;
53 }
54
55
56 int Init (u32 adr, u32 clk, u32 fnc)
57 {
58 //Set access size
59 FM4_FLASH_IF->FASZR_f.ASZ = 1;
60 FM4_WORKFLASH_IF->WFASZR_f.ASZ = 0;
61
62 return(0);
63 }
64
65 int UnInit (u32 fnc)
66 {
67 return 0;
68 }
69
70 int EraseChip (void)
71 {
72 return (0);
73 }
74
75 int EraseSector (u32 adr,u32 sz)
76 {
77 flash_unit tmp;
78 flash_ptr block_start = (flash_ptr)adr;
79
80 SET_COMMAND(DATA3, ADDRESS1);
81 SET_COMMAND(DATA1, ADDRESS2);
82 SET_COMMAND(DATA2, ADDRESS1);
83 SET_COMMAND(DATA3, ADDRESS1);
84 SET_COMMAND(DATA1, ADDRESS2);
85 SET_COMMAND(SECTOR_ERASE, block_start);
86 tmp = *(flash_ptr)block_start;
87
88 while(TOGG & (*(flash_ptr)block_start ^ (tmp = *(flash_ptr)block_start)))
89 {
90 if(TLOV & tmp) {
91 if(TOGG & (tmp ^ *(flash_ptr)block_start))
92 {
93 FlashCleanup(block_start);
94 return 1;
95 }
96 }
97 }
98
99 return (0);
100 }
101
102 int ProgramPage (u32 adr, u32 sz, unsigned char *buf)
103 {
104 flash_unit tmp;
105
106 flash_ptr flash_halfword = (flash_ptr)adr;
107 flash_unit * buffer_halfword = (flash_unit *)buf;
108
109 for (; sz; sz-=sizeof(flash_unit), flash_halfword++, buffer_halfword++)
110 {
111 SET_COMMAND(DATA3, ADDRESS1);
112 SET_COMMAND(DATA1, ADDRESS2);
113 SET_COMMAND(FLASH_WRITE, ADDRESS1);
114 SET_COMMAND(*buffer_halfword, flash_halfword);
115 tmp = *flash_halfword;
116
117 while(TOGG & (*flash_halfword ^ (tmp = *flash_halfword)))
118 {
119 if(TLOV & tmp) {
120 if(TOGG & (tmp ^ *flash_halfword))
121 {
122 FlashCleanup(flash_halfword);
123 return 1;
124 }
125 }
126 }
127 }
128
129 return (0);
130 }