Contiki 2.5
flash-at45db.h
Go to the documentation of this file.
1 /* Copyright (c) 2010, Ulf Kulau
2  *
3  * Permission is hereby granted, free of charge, to any person
4  * obtaining a copy of this software and associated documentation
5  * files (the "Software"), to deal in the Software without
6  * restriction, including without limitation the rights to use,
7  * copy, modify, merge, publish, distribute, sublicense, and/or sell
8  * copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following
10  * conditions:
11  *
12  * The above copyright notice and this permission notice shall be
13  * included in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19  * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22  * OTHER DEALINGS IN THE SOFTWARE.
23  */
24 
25 /**
26  * \addtogroup Device Interfaces
27  * @{
28  *
29  * \defgroup AT45DB_interface Atmel Flash EEPROM AT45DB interface
30  *
31  * <p>A fixed Flash EEPROM is always good to store some data. Furthermore
32  * in this project environment, the AT45DBxx1 will be used as a hardware
33  * interface between the boot section and the application section.</p>
34  *
35  * \note
36  * The function of the AT45DBxx1 is a little bit different compared to
37  * an SD-Card. The basic idea of the SD-Card is, to store one block
38  * (512Byte) into a local buffer an transfer the whole block via SPI
39  * to the SD-Card.
40  * The AT45DBxx1 has two page buffer, where the data can be collected by
41  * sending a byte via SPI to one of these buffers. If a buffer is filled,
42  * only a command is necessary and the AT45DBxx1 will copy the buffer into
43  * the flash section. To avoid latency, it is possible (and implemented)
44  * to switch between the page buffers.
45  * @{
46  *
47  */
48 
49 /**
50  * \file
51  * Atmel Flash EEPROM AT45DB interface definitions
52  * \author
53  * Ulf Kulau <kulau@ibr.cs.tu-bs.de>
54  */
55 #ifndef FLASHAT45DB_H_
56 #define FLASHAT45DB_H_
57 
58 #include "../drv/mspi-drv.h"
59 #include <stdio.h>
60 #include <util/delay.h>
61 
62 /*!
63  * SPI device order. The chip select number where the
64  * AT45DBxx1 Flash EEPROM is connected to the BCD-decimal
65  * decoder
66  */
67 #define AT45DB_CS 1
68 
69 /*!
70  * Status Register Address. Bit 7 signalizes if the device is
71  * busy.
72  * <ul>
73  * <li> 1 : not busy
74  * <li> 0 : busy
75  * </ul>
76  */
77 #define AT45DB_STATUS_REG 0xD7
78 
79 /*!
80  * Block Erase Opcode
81  */
82 #define AT45DB_BLOCK_ERASE 0x50
83 /*!
84  * Page Erase Opcode
85  */
86 #define AT45DB_PAGE_ERASE 0x81
87 /*!
88  * Main Memory Page Program Buffer 1
89  */
90 #define AT45DB_PAGE_PROGRAM_1 0x82
91 /*!
92  * Main Memory Page Program Buffer 2
93  */
94 #define AT45DB_PAGE_PROGRAM_2 0x85
95 
96 /*!
97  * Write byte(s) to buffer 1 opcode
98  */
99 #define AT45DB_BUFFER_1 0x84
100 /*!
101  * Write byte(s) to buffer 2 opcode
102  */
103 #define AT45DB_BUFFER_2 0x87
104 
105 /*!
106  * Copy Buffer 1 to page Opcode
107  */
108 #define AT45DB_BUF_1_TO_PAGE 0x83 //0x88 without auto erase
109 /*!
110  * Copy Buffer 2 to page Opcode
111  */
112 #define AT45DB_BUF_2_TO_PAGE 0x86 //0x89 without auto erase
113 /*!
114  * Read direct from Flash EEPROM page Opcode
115  */
116 #define AT45DB_PAGE_READ 0xD2
117 /*!
118  * Transfer page to buffer 2 Opcode
119  * \note Only Buffer 2 is used to readout a page, because the read
120  * respectively transfer latency is only about 200us
121  *
122  */
123 #define AT45DB_PAGE_TO_BUF 0x55 //use buffer 2
124 /*!
125  * Read buffer 2 opcode
126  * \note Only Buffer 2 is used to readout a page, because the read
127  * respectively transfer latency is only about 200us
128  */
129 #define AT45DB_READ_BUFFER 0xD6
130 
131 
132 /*!
133  * This typedef manages the buffer switching, to perform
134  * the write operation
135  */
136 typedef struct{
137 /*!
138  * Holds the active buffer
139  * <ul>
140  * <li> 0 : Active Buffer = Buffer 1
141  * <li> 1 : Active Buffer = Buffer 2
142  * </ul>
143  */
144  volatile uint8_t active_buffer;
145 /*!
146  * The specific "byte(s) to buffer" opcode for buffer 1
147  * and buffer 2
148  */
149  volatile uint8_t buffer_addr[2];
150 /*!
151  * The specific "buffer to page" opcode for buffer 1 and
152  * buffer 2
153  */
154  volatile uint8_t buf_to_page_addr[2];
155 
156 /*!
157  * Main Memory Page Program (Erase Page + Reprogram directly in one operation)
158  */
159  volatile uint8_t page_program[2];
160 }bufmgr_t;
161 
162 /*!
163  * Buffer manager allows it to improve write times, by switching
164  * the dual buffer and parallelize flash write operations. (e.g. Write
165  * to buffer 1 while buffer 2 is transfered to flash EEPROM)
166  */
167 static bufmgr_t buffer_mgr;
168 
169 /**
170  * \brief Initialize the AT45DBxx1 Flash EEPROM
171  *
172  *\return <ul>
173  * <li> 0 at45db available
174  * <li> -1 at45db not available
175  * </ul>
176  *
177  * \note No special settings are necessary to initialize
178  * the Flash memory. The standard data flash page size is
179  * 528Byte e.g. AT45DB161
180  */
181 int8_t at45db_init(void);
182 
183 /**
184  * \brief This function erases the whole chip
185  *
186  * \note The time to erase the whole chip can take
187  * up to 20sec!
188  */
189 void at45db_erase_chip(void);
190 
191 /**
192  * \brief This function erases one block (4 Kbytes)
193  *
194  * \param addr block address e.g. AT45DB161 (0 ... 511)
195  *
196  * \note The time to erase one block can take
197  * up to 45ms - 100ms!
198  */
199 void at45db_erase_block(uint16_t addr);
200 
201 /**
202  * \brief This function erases one page e.g. AT45DB161 (512 bytes)
203  *
204  * \param addr page address e.g. AT45DB161 (0 ... 4095)
205  *
206  * \note The time to erase one bock can take
207  * up to 15ms - 35ms!
208  */
209 void at45db_erase_page(uint16_t addr);
210 
211 /**
212  * \brief This function writes bytes to the active buffer, while
213  * the buffer management is done automatically.
214  *
215  * \param addr Byte address within the buffer e.g. AT45DB161 (0 ... 527)
216  * \param *buffer Pointer to local byte buffer
217  * \param bytes Number of bytes (e.g. byte buffer size) which have to
218  * be written to the active buffer
219  *
220  */
221 void at45db_write_buffer(uint16_t addr, uint8_t *buffer, uint16_t bytes);
222 
223 /**
224  * \brief This function copies the active buffer into the Flash
225  * EEPROM page. Moreover it switches the active buffer to avoid
226  * latency.
227  *
228  * \param addr page address e.g. AT45DB161 (0 ... 4095)
229  *
230  */
231 void at45db_buffer_to_page(uint16_t addr);
232 
233 /**
234  * \brief This function copies the data from the the pointer
235  * into the buffer, erases the EEPROM page and flashes the new
236  * content directly into the page
237  *
238  * \param p_addr page address e.g. AT45DB161 (0 - 4095)
239  * \param b_addr byte address within the page e.g. AT45DB161 (0 - 527)
240  * \param *buffer Pointer to local byte buffer
241  * \param bytes Number of bytes (e.g. byte buffer size) which have to
242  * be read to the local byte buffer
243  */
244 void at45db_write_page(uint16_t p_addr, uint16_t b_addr, uint8_t *buffer, uint16_t bytes);
245 
246 /**
247  * \brief Bytes can be read via buffer from a Flash EEPROM page. With this
248  * function you select the page, the start byte within the page and the
249  * number of bytes you want to read.
250  *
251  * \param p_addr page address e.g. AT45DB161 (0 - 4095)
252  * \param b_addr byte address within the page e.g. AT45DB161 (0 - 527)
253  * \param *buffer Pointer to local byte buffer
254  * \param bytes Number of bytes (e.g. byte buffer size) which have to
255  * be read to the local byte buffer
256  *
257  */
258 void at45db_read_page_buffered(uint16_t p_addr, uint16_t b_addr, uint8_t *buffer, uint16_t bytes);
259 
260 /**
261  * \brief Bytes can be read direct (bypassed) from a Flash EEPROM page. With this
262  * function you select the page, the start byte within the page and the
263  * number of bytes you want to read.
264  *
265  * \param p_addr page address e.g. AT45DB161 (0 - 4095)
266  * \param b_addr byte address within the page e.g. AT45DB161 (0 - 527)
267  * \param *buffer Pointer to local byte buffer
268  * \param bytes Number of bytes (e.g. byte buffer size) which have to
269  * be read to the local byte buffer
270  *
271  */
272 void at45db_read_page_bypassed(uint16_t p_addr, uint16_t b_addr, uint8_t *buffer, uint16_t bytes);
273 
274 /**
275  * \brief Copies the given page into the buffer 2.
276  * \note Only Buffer 2 is used to readout a page, because the read
277  * respectively transfer latency is only about 200us
278  *
279  * \param addr page address e.g. AT45DB161 (0 - 4095)
280  *
281  */
282 void at45db_page_to_buf(uint16_t addr);
283 
284 /**
285  * \brief This function readouts the buffer 2 data.
286  *
287  * \param b_addr byte address within the page e.g. AT45DB161 (0 - 527)
288  * \param *buffer Pointer to local byte buffer
289  * \param bytes Number of bytes (e.g. byte buffer size) which have to
290  * be read to the local byte buffer
291  *
292  */
293 void at45db_read_buffer(uint16_t b_addr, uint8_t *buffer, uint16_t bytes);
294 
295 /**
296  * \brief The command word of the AT45DBxx1 normally consists of 4 bytes.
297  * This function enables the chip select and sends the command (opcode +
298  * address information) to the AT45DBxx1.
299  *
300  * \param *cmd Pointer to the 4 byte command array
301  *
302  */
303 void at45db_write_cmd(uint8_t *cmd);
304 
305 /**
306  * \brief This function waits until the busy flag of the status register is set,
307  * to detect when the AT45DBxx1 device is ready to receive new commands
308  */
309 void at45db_busy_wait(void);
310 
311 
312 
313 #endif /* FLASHAT45DB_H_ */