]> git.sur5r.net Git - freertos/blob
041fd63b2d4e3a1def32c6a9195df7da955afcf9
[freertos] /
1 /***********************************************************************
2 *   Copyright(C) 2011, NXP Semiconductor
3 *   All rights reserved.
4 *
5 * Software that is described herein is for illustrative purposes only
6 * which provides customers with programming information regarding the
7 * products. This software is supplied "AS IS" without any warranties.
8 * NXP Semiconductors assumes no responsibility or liability for the
9 * use of the software, conveys no license or title under any patent,
10 * copyright, or mask work right to the product. NXP Semiconductors
11 * reserves the right to make changes in the software without
12 * notification. NXP Semiconductors also make no representation or
13 * warranty that such application will be suitable for the specified
14 * use without further testing or modification.
15 **********************************************************************/
16
17 #ifndef SPIFI_ROM_API_H
18 #define SPIFI_ROM_API_H
19
20 #include <stdint.h>
21 /* define the symbol TESTING in the environment if test output desired */
22
23 /* maintain LONGEST_PROT >= the length (in bytes) of the largest
24         protection block of any serial flash that this driver handles */
25 #define LONGEST_PROT 68
26
27 typedef uint8_t uc;
28
29 #ifndef NULL
30 #define NULL ((void *)0)
31 #endif
32
33 /* protection/sector descriptors */
34 typedef struct {
35         uint32_t base;
36         uc flags;
37         int8_t log2;
38         uint16_t rept;
39 } protEnt;
40 /* bits in the flags byte */
41 enum {RWPROT=1};
42
43 /* overall data structure includes # sectors, length of protection reg, 
44    array of descriptors 
45 typedef struct {
46         uint16_t sectors;
47         uint16_t protBytes;
48         protEnt *entries;
49 } protDesc;     */
50
51 typedef union {
52         uint16_t hw;
53         uc byte[2];
54 }stat_t;
55 /* the object that init returns, and other routines use as an operand */
56 typedef struct {
57         uint32_t base, regbase, devSize, memSize;
58         uc mfger, devType, devID, busy;
59         stat_t stat;
60         uint16_t reserved;
61         uint16_t set_prot, write_prot;
62         uint32_t mem_cmd, prog_cmd;
63         uint16_t sectors, protBytes;
64         uint32_t opts, errCheck;
65         uc erase_shifts[4], erase_ops[4];
66         protEnt *protEnts;
67         char prot[LONGEST_PROT];
68 } SPIFIobj;
69
70 /* operands of program and erase */
71 typedef struct {
72         char *dest;
73         uint32_t length;
74     char *scratch;
75         int32_t protect;
76         uint32_t options;
77 } SPIFIopers;
78
79 /* instruction classes for wait_busy */
80 typedef enum {stat_inst, block_erase, prog_inst, chip_erase} inst_type;
81
82 /* bits in options operands (MODE3, RCVCLK, and FULLCLK 
83         have the same relationship as in the Control register) */
84 #define S_MODE3 1
85 #define S_MODE0 0
86 #define S_MINIMAL 2
87 #define S_MAXIMAL 0
88 #define S_FORCE_ERASE 4
89 #define S_ERASE_NOT_REQD 8
90 #define S_CALLER_ERASE 8
91 #define S_ERASE_AS_REQD 0
92 #define S_VERIFY_PROG 0x10
93 #define S_VERIFY_ERASE 0x20
94 #define S_NO_VERIFY 0
95 #define S_RCVCLK 0x80
96 #define S_INTCLK 0
97 #define S_FULLCLK 0x40
98 #define S_HALFCLK 0
99 #define S_DUAL 0x100
100 #define S_CALLER_PROT 0x200
101 #define S_DRIVER_PROT 0
102
103 /* the following values in the first post-address memory command byte work
104    for all known quad devices that support "no opcode" operation */
105 #define NO_OPCODE_FOLLOWS 0xA5
106 #define    OPCODE_FOLLOWS 0xFF
107
108 /* basic SPI commands for serial flash */
109 #define BASE_READ_CMD        (CMD_RD<<OPCODE_SHIFT|4<<FRAMEFORM_SHIFT|UNL_DATA)
110 #define FAST_READ_CMD (CMD_READ_FAST<<OPCODE_SHIFT|4<<FRAMEFORM_SHIFT|1<<INTLEN_SHIFT|UNL_DATA)
111 #define BASE_PROG_CMD      (CMD_PROG<<OPCODE_SHIFT|4<<FRAMEFORM_SHIFT|DOUT)
112
113 /* the length of a standard     program command is 256 on all devices */
114 #define PROG_SIZE 256
115
116 /* options in obj->opts (mostly for setMulti) */
117 /* used by Winbond: send 0xA3 command so hardware can read faster */
118 #define OPT_SEND_A3        1
119 /* used by SST: send 0x38 command to enable quad and allow full command set */
120 #define OPT_SEND_38        2
121 /* used by Winbond and others: read status reg 2, check it, 
122         if necessary write it back with Quad Enable set */
123 #define OPT_35_OR02_01     4
124 /* used by Atmel: read Configuration register, if necessary set Quad Enable */
125 #define OPT_3F_OR80_3E     8
126 /* used by Numonyx to set all-quad mode: only for parts that include RSTQIO */
127 #define OPT_65_CLR_C0_61   0x10
128 /* used by Numonyx: send 0x81 command to write Volatile Configuration Register
129    to set # dummy bytes and allow XIP mode */
130 #define OPT_81          0x20
131 /* set for devices without full device erase command (Numonyx type 0x40) */
132 #define OPT_NO_DEV_ERASE 0x40
133 /* used by Macronix: status reg 2 includes selection between write-protect 
134         in status reg and command-based */
135 #define OPT_WPSEL       0x80
136 /* set when protection data has been read into the SPIFI object */
137 #define OPT_PROT_READ  0x100
138 /* set if device needs 4-byte address (and maybe 0x4B command = use 4-byte address) */
139 #define OPT_4BAD       0x200
140 /* set if setMulti should set the Dual bit in Control reg */
141 #define OPT_DUAL           0x400
142 /* send "# dummy bits" in C0 command to Winbond */
143 #define OPT_C0         0x800
144 /* set QE for Chingis */
145 #define OPT_05_OR40_01 0x1000
146 /* write status does not go busy */
147 #define OPT_01_NO_BUSY 0x2000
148 /* protection mode bits moved from protMode byte to opts  Fri May 13 2011 */
149 #define OPT_PROT_STAT 0x4000
150 #define OPT_PROT_REG  0x8000
151 #define OPT_PROT_CMD3 0x10000
152 #define OPT_PROT_CMDE 0x20000
153 #define OPT_PROT_MASK 0x3C000
154
155 #define OPT_ALL_QUAD  0x40000
156
157 #ifndef OMIT_ROM_TABLE
158 /* interface to ROM API */
159 typedef struct {
160   int32_t (*spifi_init)      (SPIFIobj *obj, uint32_t csHigh, uint32_t options, 
161                           uint32_t mhz);
162   int32_t (*spifi_program)   (SPIFIobj *obj, char *source, SPIFIopers *opers);
163   int32_t (*spifi_erase)     (SPIFIobj *obj, SPIFIopers *opers);
164   /* mode switching */
165   void (*cancel_mem_mode)(SPIFIobj *obj);
166   void (*set_mem_mode)   (SPIFIobj *obj);
167
168   /* mid level functions */
169   int32_t (*checkAd)         (SPIFIobj *obj, SPIFIopers *opers);
170   int32_t (*setProt)         (SPIFIobj *obj, SPIFIopers *opers, char *change, 
171                           char *saveProt);
172   int32_t (*check_block)     (SPIFIobj *obj, char *source, SPIFIopers *opers, 
173                           uint32_t check_program);
174   int32_t (*send_erase_cmd)  (SPIFIobj *obj, uint8_t op, uint32_t addr);
175   uint32_t (*ck_erase)   (SPIFIobj *obj, uint32_t *addr, uint32_t length);
176   int32_t (*prog_block)      (SPIFIobj *obj, char *source, SPIFIopers *opers, 
177                           uint32_t *left_in_page);
178   uint32_t (*ck_prog)    (SPIFIobj *obj, char *source, char *dest, uint32_t length);
179
180   /* low level functions */
181   void(*setSize)         (SPIFIobj *obj, int32_t value);
182   int32_t (*setDev)          (SPIFIobj *obj, uint32_t opts, uint32_t mem_cmd, 
183                           uint32_t prog_cmd);
184   uint32_t (*cmd)        (uc op, uc addrLen, uc intLen, uint16_t len);
185   uint32_t (*readAd)     (SPIFIobj *obj, uint32_t cmd, uint32_t addr);
186   void (*send04)         (SPIFIobj *obj, uc op, uc len, uint32_t value);
187   void (*wren_sendAd)    (SPIFIobj *obj, uint32_t cmd, uint32_t addr, uint32_t value);
188   int32_t (*write_stat)      (SPIFIobj *obj, uc len, uint16_t value);
189   int32_t (*wait_busy)       (SPIFIobj *obj, uc prog_or_erase);
190 } SPIFI_RTNS;
191
192 #define define_spifi_romPtr(name) const SPIFI_RTNS *name=*((SPIFI_RTNS **)SPIFI_ROM_PTR)
193 #endif /* OMIT_ROM_TABLE */
194
195 #ifdef USE_SPIFI_LIB
196 extern SPIFI_RTNS spifi_table;
197 #endif  /* USE_SPIFI_LIB */
198  
199 /* example of using this interface:
200 #include "spifi_rom_api.h"
201 #define CSHIGH 4
202 #define SPIFI_MHZ 80
203 #define source_data_ad (char *)1234
204
205         int32_t rc;
206         SPIFIopers opers;
207
208         define_spifi_romPtr(spifi);
209         SPIFIobj *obj = malloc(sizeof(SPIFIobj));
210         if (!obj) { can't allocate memory }
211
212         rc = spifi->spifi_init (obj, CSHIGH, S_FULLCLK+S_RCVCLK, SPIFI_MHZ);
213         if (rc) { investigate init error rc }
214         printf ("the serial flash contains %d bytes\n", obj->devSize);
215
216         opers.dest = where_to_program;
217         opers.length = how_many_bytes;
218         opers.scratch = NULL;                   // unprogrammed data is not saved/restored
219         opers.protect = -1;                             // save & restore protection
220         opers.options = S_VERIFY_PROG;
221
222         rc = spifi->spifi_program (obj, source_data_ad, &opers);
223         if (rc) { investigate program error rc }
224 */
225
226 /* these are for normal users, including boot code */
227 int32_t spifi_init (SPIFIobj *obj, uint32_t csHigh, uint32_t options, uint32_t mhz);
228 int32_t spifi_program (SPIFIobj *obj, char *source, SPIFIopers *opers);
229 int32_t spifi_erase (SPIFIobj *obj, SPIFIopers *opers);
230
231 /* these are used by the manufacturer-specific init functions */
232 void setSize (SPIFIobj *obj, int32_t value);
233 int32_t setDev (SPIFIobj *obj, uint32_t opts, uint32_t mem_cmd, uint32_t prog_cmd);
234 uint32_t read04(SPIFIobj *obj, uc op, uc len);
235 int32_t write_stat (SPIFIobj *obj, uc len, uint16_t value);
236 void setProtEnts(SPIFIobj *obj, const protEnt *p, uint32_t protTabLen);
237
238 /* needs to be defined for each platform */
239 void pullMISO(int high);
240
241 #ifdef TESTING
242 /* used by testing code */
243 unsigned short getProtBytes (SPIFIobj *obj, unsigned short *sectors);
244 /* predeclare a debug routine */
245 void wait_sample (volatile unsigned *addr, unsigned mask, unsigned value);
246 #endif
247
248 #endif /* SPIFI_ROM_API_H */