LPCOpen Platform
LPCOpen Platform for NXP LPC Microcontrollers
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
spifi_rom_api.h
Go to the documentation of this file.
1 /*
2  * @brief SPIFI ROM driver functions
3  *
4  * @note
5  * Copyright(C) NXP Semiconductors, 2012
6  * All rights reserved.
7  *
8  * @par
9  * Software that is described herein is for illustrative purposes only
10  * which provides customers with programming information regarding the
11  * LPC products. This software is supplied "AS IS" without any warranties of
12  * any kind, and NXP Semiconductors and its licensor disclaim any and
13  * all warranties, express or implied, including all implied warranties of
14  * merchantability, fitness for a particular purpose and non-infringement of
15  * intellectual property rights. NXP Semiconductors assumes no responsibility
16  * or liability for the use of the software, conveys no license or rights under any
17  * patent, copyright, mask work right, or any other intellectual property rights in
18  * or to any products. NXP Semiconductors reserves the right to make changes
19  * in the software without notification. NXP Semiconductors also makes no
20  * representation or warranty that such application will be suitable for the
21  * specified use without further testing or modification.
22  *
23  * @par
24  * Permission to use, copy, modify, and distribute this software and its
25  * documentation is hereby granted, under NXP Semiconductors' and its
26  * licensor's relevant copyrights in the software, without fee, provided that it
27  * is used in conjunction with NXP Semiconductors microcontrollers. This
28  * copyright, permission, and disclaimer notice must appear in all copies of
29  * this code.
30  */
31 
32 #ifndef __SPIFI_ROM_API_H_
33 #define __SPIFI_ROM_API_H_
34 
35 #include "chip.h"
36 #include <stdint.h>
37 
38 #ifdef __cplusplus
39 extern "C" {
40 #endif
41 
42 /* define the symbol TESTING in the environment if test output desired */
43 
48 /* maintain LONGEST_PROT >= the length (in bytes) of the largest
49  protection block of any serial flash that this driver handles */
50 #define LONGEST_PROT 68
51 
52 typedef uint8_t uc;
53 
54 #ifndef NULL
55 #define NULL ((void *) 0)
56 #endif
57 
59 typedef struct {
61  uc flags;
62  int8_t log2;
63  uint16_t rept;
64 } protEnt;
65 /* bits in the flags byte */
66 enum {RWPROT = 1};
67 
68 #if 0
69 
70 /* overall data structure includes # sectors, length of protection reg,
71  array of descriptors */
72 typedef struct {
73  uint16_t sectors;
74  uint16_t protBytes;
75  protEnt *entries;
76 } protDesc;
77 #endif
78 
79 typedef union {
80  uint16_t hw;
81  uc byte[2];
82 } stat_t;
84 typedef struct {
85  uint32_t base, regbase, devSize, memSize;
86  uc mfger, devType, devID, busy;
88  uint16_t reserved;
89  uint16_t set_prot, write_prot;
90  uint32_t mem_cmd, prog_cmd;
91  uint16_t sectors, protBytes;
92  uint32_t opts, errCheck;
93  uc erase_shifts[4], erase_ops[4];
95  char prot[LONGEST_PROT];
96 } SPIFIobj;
97 
99 typedef struct {
100  char *dest;
102  char *scratch;
103  int32_t protect;
105 } SPIFIopers;
106 
109 
119 #define S_MODE3 1
120 
122 #define S_MODE0 0
123 
125 #define S_MINIMAL 2
126 
128 #define S_MAXIMAL 0
129 
134 #define S_RCVCLK 0x80
135 
137 #define S_INTCLK 0
138 
142 #define S_FULLCLK 0x40
143 
146 #define S_HALFCLK 0
147 
150 #define S_DUAL 0x100
151 
163 #define S_FORCE_ERASE 4
164 
166 #define S_ERASE_NOT_REQD 8
167 
169 #define S_CALLER_ERASE 8
170 
172 #define S_ERASE_AS_REQD 0
173 
175 #define S_VERIFY_PROG 0x10
176 
178 #define S_VERIFY_ERASE 0x20
179 
181 #define S_NO_VERIFY 0
182 
184 #define S_CALLER_PROT 0x200
185 
187 #define S_DRIVER_PROT 0
188 
193 /* the following values in the first post-address memory command byte work
194  for all known quad devices that support "no opcode" operation */
195 #define NO_OPCODE_FOLLOWS 0xA5
196 #define OPCODE_FOLLOWS 0xFF
197 
198 /* basic SPI commands for serial flash */
199 #define BASE_READ_CMD (CMD_RD << OPCODE_SHIFT | 4 << FRAMEFORM_SHIFT | UNL_DATA)
200 #define FAST_READ_CMD (CMD_READ_FAST << OPCODE_SHIFT | 4 << FRAMEFORM_SHIFT | 1 << INTLEN_SHIFT | UNL_DATA)
201 #define BASE_PROG_CMD (CMD_PROG << OPCODE_SHIFT | 4 << FRAMEFORM_SHIFT | DOUT)
202 
203 /* the length of a standard program command is 256 on all devices */
204 #define PROG_SIZE 256
205 
206 /* options in obj->opts (mostly for setMulti) */
207 /* used by Winbond: send 0xA3 command so hardware can read faster */
208 #define OPT_SEND_A3 1
209 /* used by SST: send 0x38 command to enable quad and allow full command set */
210 #define OPT_SEND_38 2
211 /* used by Winbond and others: read status reg 2, check it,
212  if necessary write it back with Quad Enable set */
213 #define OPT_35_OR02_01 4
214 /* used by Atmel: read Configuration register, if necessary set Quad Enable */
215 #define OPT_3F_OR80_3E 8
216 /* used by Numonyx to set all-quad mode: only for parts that include RSTQIO */
217 #define OPT_65_CLR_C0_61 0x10
218 /* used by Numonyx: send 0x81 command to write Volatile Configuration Register
219  to set # dummy bytes and allow XIP mode */
220 #define OPT_81 0x20
221 /* set for devices without full device erase command (Numonyx type 0x40) */
222 #define OPT_NO_DEV_ERASE 0x40
223 /* used by Macronix: status reg 2 includes selection between write-protect
224  in status reg and command-based */
225 #define OPT_WPSEL 0x80
226 /* set when protection data has been read into the SPIFI object */
227 #define OPT_PROT_READ 0x100
228 /* set if device needs 4-byte address (and maybe 0x4B command = use 4-byte address) */
229 #define OPT_4BAD 0x200
230 /* set if setMulti should set the Dual bit in Control reg */
231 #define OPT_DUAL 0x400
232 /* send "# dummy bits" in C0 command to Winbond */
233 #define OPT_C0 0x800
234 /* set QE for Chingis */
235 #define OPT_05_OR40_01 0x1000
236 /* write status does not go busy */
237 #define OPT_01_NO_BUSY 0x2000
238 /* protection mode bits moved from protMode byte to opts Fri May 13 2011 */
239 #define OPT_PROT_STAT 0x4000
240 #define OPT_PROT_REG 0x8000
241 #define OPT_PROT_CMD3 0x10000
242 #define OPT_PROT_CMDE 0x20000
243 #define OPT_PROT_MASK 0x3C000
244 
245 #define OPT_ALL_QUAD 0x40000
246 
247 #ifndef OMIT_ROM_TABLE
248 /* interface to ROM API */
249 typedef struct {
250  int32_t (*spifi_init)(SPIFIobj *obj, uint32_t csHigh, uint32_t options,
251  uint32_t mhz);
252  int32_t (*spifi_program)(SPIFIobj *obj, char *source, SPIFIopers *opers);
253  int32_t (*spifi_erase)(SPIFIobj *obj, SPIFIopers *opers);
254  /* mode switching */
255  void (*cancel_mem_mode)(SPIFIobj *obj);
256  void (*set_mem_mode)(SPIFIobj *obj);
257 
258  /* mid level functions */
259  int32_t (*checkAd)(SPIFIobj *obj, SPIFIopers *opers);
260  int32_t (*setProt)(SPIFIobj *obj, SPIFIopers *opers, char *change,
261  char *saveProt);
262  int32_t (*check_block)(SPIFIobj *obj, char *source, SPIFIopers *opers,
263  uint32_t check_program);
264  int32_t (*send_erase_cmd)(SPIFIobj *obj, uint8_t op, uint32_t addr);
265  uint32_t (*ck_erase)(SPIFIobj *obj, uint32_t *addr, uint32_t length);
266  int32_t (*prog_block)(SPIFIobj *obj, char *source, SPIFIopers *opers,
267  uint32_t *left_in_page);
268  uint32_t (*ck_prog)(SPIFIobj *obj, char *source, char *dest, uint32_t length);
269 
270  /* low level functions */
271  void (*setSize)(SPIFIobj *obj, int32_t value);
272  int32_t (*setDev)(SPIFIobj *obj, uint32_t opts, uint32_t mem_cmd,
273  uint32_t prog_cmd);
274  uint32_t (*cmd)(uc op, uc addrLen, uc intLen, uint16_t len);
276  void (*send04)(SPIFIobj *obj, uc op, uc len, uint32_t value);
277  void (*wren_sendAd)(SPIFIobj *obj, uint32_t cmd, uint32_t addr, uint32_t value);
278  int32_t (*write_stat)(SPIFIobj *obj, uc len, uint16_t value);
279  int32_t (*wait_busy)(SPIFIobj *obj, uc prog_or_erase);
280 } SPIFI_RTNS;
281 
282 #define SPIFI_ROM_PTR 0x10400118
283 
284 #define define_spifi_romPtr(name) const SPIFI_RTNS * name = *((SPIFI_RTNS * *) SPIFI_ROM_PTR)
285 #endif /* OMIT_ROM_TABLE */
286 
287 #ifdef USE_SPIFI_LIB
288 extern SPIFI_RTNS spifi_table;
289 #endif /* USE_SPIFI_LIB */
290 
291 /* example of using this interface:
292  #include "spifi_rom_api.h"
293  #define CSHIGH 4
294  #define SPIFI_MHZ 80
295  #define source_data_ad (char *)1234
296 
297  int32_t rc;
298  SPIFIopers opers;
299 
300  define_spifi_romPtr(spifi);
301  SPIFIobj *obj = malloc(sizeof(SPIFIobj));
302  if (!obj) { can't allocate memory }
303 
304  rc = spifi->spifi_init (obj, CSHIGH, S_FULLCLK+S_RCVCLK, SPIFI_MHZ);
305  if (rc) { investigate init error rc }
306  printf ("the serial flash contains %d bytes\n", obj->devSize);
307 
308  opers.dest = where_to_program;
309  opers.length = how_many_bytes;
310  opers.scratch = NULL; // unprogrammed data is not saved/restored
311  opers.protect = -1; // save & restore protection
312  opers.options = S_VERIFY_PROG;
313 
314  rc = spifi->spifi_program (obj, source_data_ad, &opers);
315  if (rc) { investigate program error rc }
316  */
317 
318 /* these are for normal users, including boot code */
319 int32_t spifi_init (SPIFIobj *obj, uint32_t csHigh, uint32_t options, uint32_t mhz);
320 
321 int32_t spifi_program (SPIFIobj *obj, char *source, SPIFIopers *opers);
322 
323 int32_t spifi_erase (SPIFIobj *obj, SPIFIopers *opers);
324 
325 /* these are used by the manufacturer-specific init functions */
326 void setSize (SPIFIobj *obj, int32_t value);
327 
328 int32_t setDev (SPIFIobj *obj, uint32_t opts, uint32_t mem_cmd, uint32_t prog_cmd);
329 
330 uint32_t read04(SPIFIobj *obj, uc op, uc len);
331 
332 int32_t write_stat (SPIFIobj *obj, uc len, uint16_t value);
333 
334 void setProtEnts(SPIFIobj *obj, const protEnt *p, uint32_t protTabLen);
335 
336 /* needs to be defined for each platform */
337 void pullMISO(int high);
338 
339 #ifdef TESTING
340 /* used by testing code */
341 unsigned short getProtBytes (SPIFIobj *obj, unsigned short *sectors);
342 
343 /* predeclare a debug routine */
344 void wait_sample (volatile unsigned *addr, unsigned mask, unsigned value);
345 
346 #endif
347 
352  #ifdef __cplusplus
353 }
354 #endif
355 
356 #endif /* __SPIFI_ROM_API_H_ */