blob: 525f866f37872f8703c454b2f0033a60830c27c6 [file] [log] [blame]
Tamas Banf70ef8c2017-12-19 15:35:09 +00001/*
2 * Copyright (c) 2017 Nordic Semiconductor ASA
3 * Copyright (c) 2016 Intel Corporation
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8/**
9 * @file
10 * @brief Public API for FLASH drivers
11 */
12
13#ifndef __FLASH_H__
14#define __FLASH_H__
15
16/**
17 * @brief FLASH Interface
18 * @defgroup flash_interface FLASH Interface
19 * @ingroup io_interfaces
20 * @{
21 */
22
23#include <zephyr/types.h>
24#include <stddef.h>
25#include <sys/types.h>
26#include <device.h>
27
28#ifdef __cplusplus
29extern "C" {
30#endif
31
32#if defined(CONFIG_FLASH_PAGE_LAYOUT)
33struct flash_pages_layout {
34 size_t pages_count; /* count of pages sequence of the same size */
35 size_t pages_size;
36};
37#endif /* CONFIG_FLASH_PAGE_LAYOUT */
38
39typedef int (*flash_api_read)(struct device *dev, off_t offset, void *data,
40 size_t len);
41typedef int (*flash_api_write)(struct device *dev, off_t offset,
42 const void *data, size_t len);
43typedef int (*flash_api_erase)(struct device *dev, off_t offset, size_t size);
44typedef int (*flash_api_write_protection)(struct device *dev, bool enable);
45
46#if defined(CONFIG_FLASH_PAGE_LAYOUT)
47/**
48 * @brief Retrieve a flash device's layout.
49 *
50 * A flash device layout is a run-length encoded description of the
51 * pages on the device. (Here, "pages" means the smallest erasable
52 * areas on the flash device.)
53 *
54 * For flash memories which have uniform page sizes, this routine
55 * returns an array of length 1, which specifies the page size and
56 * number of pages in the memory.
57 *
58 * Layouts for flash memories with nonuniform page sizes will be
59 * returned as an array with multiple elements, each of which
60 * describes a group of pages that all have the same size. In this
61 * case, the sequence of array elements specifies the order in which
62 * these groups occur on the device.
63 *
64 * @param dev Flash device whose layout to retrieve.
65 * @param layout The flash layout will be returned in this argument.
66 * @param layout_size The number of elements in the returned layout.
67 */
68typedef void (*flash_api_pages_layout)(struct device *dev,
69 const struct flash_pages_layout **layout,
70 size_t *layout_size);
71#endif /* CONFIG_FLASH_PAGE_LAYOUT */
72
73struct flash_driver_api {
74 flash_api_read read;
75 flash_api_write write;
76 flash_api_erase erase;
77 flash_api_write_protection write_protection;
78#if defined(CONFIG_FLASH_PAGE_LAYOUT)
79 flash_api_pages_layout page_layout;
80#endif /* CONFIG_FLASH_PAGE_LAYOUT */
81 const size_t write_block_size;
82};
83
84/**
85 * @brief Read data from flash
86 *
87 * @param dev : flash dev
88 * @param offset : Offset (byte aligned) to read
89 * @param data : Buffer to store read data
90 * @param len : Number of bytes to read.
91 *
92 * @return 0 on success, negative errno code on fail.
93 */
94__syscall int flash_read(struct device *dev, off_t offset, void *data,
95 size_t len);
96
97static inline int _impl_flash_read(struct device *dev, off_t offset, void *data,
98 size_t len)
99{
100 const struct flash_driver_api *api = dev->driver_api;
101
102 return api->read(dev, offset, data, len);
103}
104
105/**
106 * @brief Write buffer into flash memory.
107 *
108 * Prior to the invocation of this API, the flash_write_protection_set needs
109 * to be called first to disable the write protection.
110 *
111 * @param dev : flash device
112 * @param offset : starting offset for the write
113 * @param data : data to write
114 * @param len : Number of bytes to write
115 *
116 * @return 0 on success, negative errno code on fail.
117 */
118__syscall int flash_write(struct device *dev, off_t offset, const void *data,
119 size_t len);
120
121static inline int _impl_flash_write(struct device *dev, off_t offset,
122 const void *data, size_t len)
123{
124 const struct flash_driver_api *api = dev->driver_api;
125
126 return api->write(dev, offset, data, len);
127}
128
129/**
130 * @brief Erase part or all of a flash memory
131 *
132 * Acceptable values of erase size and offset are subject to
133 * hardware-specific multiples of page size and offset. Please check
134 * the API implemented by the underlying sub driver, for example by
135 * using flash_get_page_info_by_offs() if that is supported by your
136 * flash driver.
137 *
138 * Prior to the invocation of this API, the flash_write_protection_set needs
139 * to be called first to disable the write protection.
140 *
141 * @param dev : flash device
142 * @param offset : erase area starting offset
143 * @param size : size of area to be erased
144 *
145 * @return 0 on success, negative errno code on fail.
146 *
147 * @see flash_get_page_info_by_offs()
148 * @see flash_get_page_info_by_idx()
149 */
150__syscall int flash_erase(struct device *dev, off_t offset, size_t size);
151
152static inline int _impl_flash_erase(struct device *dev, off_t offset,
153 size_t size)
154{
155 const struct flash_driver_api *api = dev->driver_api;
156
157 return api->erase(dev, offset, size);
158}
159
160/**
161 * @brief Enable or disable write protection for a flash memory
162 *
163 * This API is required to be called before the invocation of write or erase
164 * API. Please note that on some flash components, the write protection is
165 * automatically turned on again by the device after the completion of each
166 * write or erase calls. Therefore, on those flash parts, write protection needs
167 * to be disabled before each invocation of the write or erase API. Please refer
168 * to the sub-driver API or the data sheet of the flash component to get details
169 * on the write protection behavior.
170 *
171 * @param dev : flash device
172 * @param enable : enable or disable flash write protection
173 *
174 * @return 0 on success, negative errno code on fail.
175 */
176__syscall int flash_write_protection_set(struct device *dev, bool enable);
177
178static inline int _impl_flash_write_protection_set(struct device *dev,
179 bool enable)
180{
181 const struct flash_driver_api *api = dev->driver_api;
182
183 return api->write_protection(dev, enable);
184}
185
186struct flash_pages_info {
187 off_t start_offset; /* offset from the base of flash address */
188 size_t size;
189 u32_t index;
190};
191
192#if defined(CONFIG_FLASH_PAGE_LAYOUT)
193/**
194 * @brief Get size and start offset of flash page at certain flash offset.
195 *
196 * @param dev flash device
197 * @param offset Offset within the page
198 * @param info Page Info structure to be filled
199 *
200 * @return 0 on success, -EINVAL if page of the offset doesn't exist.
201 */
202__syscall int flash_get_page_info_by_offs(struct device *dev, off_t offset,
203 struct flash_pages_info *info);
204
205/**
206 * @brief Get size and start offset of flash page of certain index.
207 *
208 * @param dev flash device
209 * @param page_index Index of the page. Index are counted from 0.
210 * @param info Page Info structure to be filled
211 *
212 * @return 0 on success, -EINVAL if page of the index doesn't exist.
213 */
214__syscall int flash_get_page_info_by_idx(struct device *dev, u32_t page_index,
215 struct flash_pages_info *info);
216
217/**
218 * @brief Get number of flash pages.
219 *
220 * @param dev flash device
221 *
222 * @return Number of flash pages.
223 */
224__syscall size_t flash_get_page_count(struct device *dev);
225
226/**
227 * @brief Callback type for iterating over flash pages present on a device.
228 *
229 * The callback should return true to continue iterating, and false to halt.
230 *
231 * @param info Information for current page
232 * @param data Private data for callback
233 * @return True to continue iteration, false to halt iteration.
234 * @see flash_page_foreach()
235 */
236typedef bool (*flash_page_cb)(const struct flash_pages_info *info, void *data);
237
238/**
239 * @brief Iterate over flash pages on a device
240 *
241 * This routine iterates over all flash pages on the given device,
242 * ordered by increasing start offset. For each page, it invokes the
243 * given callback, passing it the page's information and a private
244 * data object.
245 *
246 * @param dev Device whose pages to iterate over
247 * @param cb Callback to invoke for each flash page
248 * @param data Private data for callback function
249 */
250void flash_page_foreach(struct device *dev, flash_page_cb cb, void *data);
251#endif /* CONFIG_FLASH_PAGE_LAYOUT */
252
253/**
254 * @brief Get the minimum write block size supported by the driver
255 *
256 * The Write block size supported by the driver might defer from the write
257 * block size of memory used because the driver might implements write-modify
258 * algorithm.
259 *
260 * @param dev flash device
261 *
262 * @return write block size in Bytes.
263 */
264__syscall size_t flash_get_write_block_size(struct device *dev);
265
266static inline size_t _impl_flash_get_write_block_size(struct device *dev)
267{
268 const struct flash_driver_api *api = dev->driver_api;
269
270 return api->write_block_size;
271}
272
273#ifdef __cplusplus
274}
275#endif
276
277/**
278 * @}
279 */
280
281#include <syscalls/flash.h>
282
283#endif /* _FLASH_H_ */