Contiki 2.5
flash-at45db.c
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  * \addtogroup AT45DB_interface
30  * @{
31  */
32 
33 /**
34  * \file
35  * Atmel Flash EEPROM AT45DB interface implementation
36  * \author
37  * Ulf Kulau <kulau@ibr.cs.tu-bs.de>
38  */
39 
40 #include "flash-at45db.h"
41 
42 int8_t at45db_init(void) {
43  uint8_t i = 0, id = 0;
44  /*setup buffer manager to perform write and read operations*/
45  buffer_mgr.active_buffer = 0;
46  buffer_mgr.buffer_addr[0] = AT45DB_BUFFER_1;
47  buffer_mgr.buffer_addr[1] = AT45DB_BUFFER_2;
48  buffer_mgr.buf_to_page_addr[0] = AT45DB_BUF_1_TO_PAGE;
49  buffer_mgr.buf_to_page_addr[1] = AT45DB_BUF_2_TO_PAGE;
50  buffer_mgr.page_program[0] = AT45DB_PAGE_PROGRAM_1;
51  buffer_mgr.page_program[1] = AT45DB_PAGE_PROGRAM_2;
52 
54  /*init mspi in mode3, at chip select pin 3 and max baud rate*/
56 
57  while (id != 0x1F) {
59  mspi_transceive(0x9F);
60  id = mspi_transceive(0x00);
62  _delay_ms(10);
63  if (i++ > 10) {
64  return -1;
65  }
66  }
67  return 0;
68 
69 }
70 
71 void at45db_erase_chip(void) {
72  /*chip erase command consists of 4 byte*/
73  uint8_t cmd[4] = { 0xC7, 0x94, 0x80, 0x9A };
74  at45db_write_cmd(&cmd[0]);
76  /*wait until AT45DB161 is ready again*/
80 }
81 
82 void at45db_erase_block(uint16_t addr) {
83  /*block erase command consists of 4 byte*/
84  uint8_t cmd[4] = { AT45DB_BLOCK_ERASE, (uint8_t) (addr >> 3),
85  (uint8_t) (addr << 5), 0x00 };
86  at45db_write_cmd(&cmd[0]);
88  /*wait until AT45DB161 is ready again*/
92 }
93 
94 void at45db_erase_page(uint16_t addr) {
95  /*block erase command consists of 4 byte*/
96  uint8_t cmd[4] = { AT45DB_PAGE_ERASE, (uint8_t) (addr >> 6),
97  (uint8_t) (addr << 2), 0x00 };
98  at45db_write_cmd(&cmd[0]);
100  /*wait until AT45DB161 is ready again*/
104 }
105 
106 void at45db_write_buffer(uint16_t addr, uint8_t *buffer, uint16_t bytes) {
107  uint16_t i;
108  /*block erase command consists of 4 byte*/
109  uint8_t cmd[4] = { buffer_mgr.buffer_addr[buffer_mgr.active_buffer], 0x00,
110  (uint8_t) (addr >> 8), (uint8_t) (addr) };
111 
112  at45db_write_cmd(&cmd[0]);
113 
114  for (i = 0; i < bytes; i++) {
115  mspi_transceive(~(*buffer++));
116  }
117 
119 }
120 
121 void at45db_buffer_to_page(uint16_t addr) {
122  /*wait until AT45DB161 is ready again*/
124  /*write active buffer to page command consists of 4 byte*/
125  uint8_t cmd[4] = { buffer_mgr.buf_to_page_addr[buffer_mgr.active_buffer],
126  (uint8_t) (addr >> 6), (uint8_t) (addr << 2), 0x00 };
127  at45db_write_cmd(&cmd[0]);
129  /* switch active buffer to allow the other one to be written,
130  * while these buffer is copied to the Flash EEPROM page*/
131  buffer_mgr.active_buffer ^= 1;
132 }
133 
134 
135 void at45db_write_page(uint16_t p_addr, uint16_t b_addr, uint8_t *buffer, uint16_t bytes) {
136  uint16_t i;
137  /*block erase command consists of 4 byte*/
138  uint8_t cmd[4] = { buffer_mgr.page_program[buffer_mgr.active_buffer],
139  (uint8_t) (p_addr >> 6), ((uint8_t) (p_addr << 2) & 0xFC) | ((uint8_t) (b_addr >> 8) & 0x3), (uint8_t) (b_addr) };
140 
141  at45db_write_cmd(&cmd[0]);
142 
143  for (i = 0; i < bytes; i++) {
144  mspi_transceive(~(*buffer++));
145  }
146 
148 
149  /* switch active buffer to allow the other one to be written,
150  * while these buffer is copied to the Flash EEPROM page*/
151  buffer_mgr.active_buffer ^= 1;
152 }
153 
154 void at45db_read_page_buffered(uint16_t p_addr, uint16_t b_addr,
155  uint8_t *buffer, uint16_t bytes) {
156  /*wait until AT45DB161 is ready again*/
158  at45db_page_to_buf(p_addr);
159  at45db_read_buffer(b_addr, buffer, bytes);
160 }
161 
162 void at45db_read_page_bypassed(uint16_t p_addr, uint16_t b_addr,
163  uint8_t *buffer, uint16_t bytes) {
164  uint16_t i;
165  /*wait until AT45DB161 is ready again*/
167  /* read bytes directly from page command consists of 4 cmd bytes and
168  * 4 don't care */
169  uint8_t cmd[4] = { AT45DB_PAGE_READ, (uint8_t) (p_addr >> 6),
170  (((uint8_t) (p_addr << 2)) & 0xFC) | ((uint8_t) (b_addr >> 8)),
171  (uint8_t) (b_addr) };
172  at45db_write_cmd(&cmd[0]);
173  for (i = 0; i < 4; i++) {
174  mspi_transceive(0x00);
175  }
176  /*now the data bytes can be received*/
177  for (i = 0; i < bytes; i++) {
178  *buffer++ = ~mspi_transceive(MSPI_DUMMY_BYTE);
179  }
181 }
182 
183 void at45db_page_to_buf(uint16_t addr) {
184 
185  /*write active buffer to page command consists of 4 byte*/
186  uint8_t cmd[4] = { AT45DB_PAGE_TO_BUF, (uint8_t) (addr >> 6),
187  (uint8_t) (addr << 2), 0x00 };
188  at45db_write_cmd(&cmd[0]);
190  /* switch active buffer to allow the other one to be written,
191  * while these buffer is copied to the Flash EEPROM page*/
192  //buffer_mgr.active_buffer ^= 1;
194 
195 }
196 
197 void at45db_read_buffer(uint16_t b_addr, uint8_t *buffer, uint16_t bytes) {
198  uint16_t i;
199  uint8_t cmd[4] = { AT45DB_READ_BUFFER, 0x00, (uint8_t) (b_addr >> 8),
200  (uint8_t) (b_addr) };
202  at45db_write_cmd(&cmd[0]);
203  mspi_transceive(0x00);
204 
205  for (i = 0; i < bytes; i++) {
206  *buffer++ = ~mspi_transceive(0x00);
207  }
209 }
210 
211 void at45db_write_cmd(uint8_t *cmd) {
212  uint8_t i;
214  for (i = 0; i < 4; i++) {
215  mspi_transceive(*cmd++);
216  }
217 }
218 
219 void at45db_busy_wait(void) {
222  while ((mspi_transceive(MSPI_DUMMY_BYTE) >> 7) != 0x01) {
223  }
225 }
226