00001
00038 #ifndef FLASH_AT45_DEVICE_H_INCLUDED
00039 #define FLASH_AT45_DEVICE_H_INCLUDED
00040
00041 #include <flash/at45.h>
00042
00062
00063 enum at45_device_flag {
00064 AT45_FLAG_VALID,
00065 AT45_FLAG_PROTECTED,
00066 };
00067
00068
00069 struct at45_device;
00070
00075 typedef bool (*at45_next_call_t)(struct at45_device *at45d);
00076
00078 struct at45_device {
00080 struct spi_master *spim;
00082 struct spi_device *spid;
00084 spi_id_t spi_id;
00086 at45_next_call_t next;
00088 uint32_t size;
00090 uint16_t page_size;
00092 uint8_t flags;
00099 unsigned char cmdrsp[5];
00100 };
00101
00113 static inline void at45_request(struct at45_device *at45d,
00114 struct workqueue_task *task)
00115 {
00116 spi_request_bus(at45d->spim, task);
00117 }
00118
00126 static inline void at45_release(struct at45_device *at45d)
00127 {
00128 spi_release_bus(at45d->spim);
00129 }
00130
00138 static inline void at45_select(struct at45_device *at45d)
00139 {
00140 spi_select_device(at45d->spi_id, at45d->spim, at45d->spid);
00141 }
00142
00150 static inline void at45_deselect(struct at45_device *at45d)
00151 {
00152 spi_deselect_device(at45d->spi_id, at45d->spim, at45d->spid);
00153 }
00154
00167 static inline void at45_write_cmd(struct at45_device *at45d, uint8_t size)
00168 {
00169 assert(size <= sizeof(at45d->cmdrsp));
00170
00171 spi_write(at45d->spi_id, at45d->spim, at45d->cmdrsp, size);
00172 }
00173
00186 static inline void at45_read_rsp(struct at45_device *at45d, uint8_t size)
00187 {
00188 assert(size <= sizeof(at45d->cmdrsp));
00189
00190 spi_read(at45d->spi_id, at45d->spim, at45d->cmdrsp, size);
00191 }
00192
00200 static inline void at45_cmd_read_status_reg(struct at45_device *at45d)
00201 {
00202 at45d->cmdrsp[0] = AT45_CMD_READ_STATUS_REG;
00203 at45_write_cmd(at45d, 1);
00204 }
00205
00213 static inline void at45_cmd_read_id(struct at45_device *at45d)
00214 {
00215 at45d->cmdrsp[0] = AT45_CMD_READ_ID;
00216 at45_write_cmd(at45d, 1);
00217 }
00218
00228 static inline void at45_cmd_cont_array_read(struct at45_device *at45d, uint16_t page,
00229 uint16_t pos)
00230 {
00231 assert(!(page & ~AT45_PAGE_ADDR_MASK));
00232 assert(!(pos & ~AT45_PAGE_POS_MASK));
00233
00234 at45d->cmdrsp[0] = AT45_CMD_CONTINOUS_ARRAY_READ;
00235
00236
00237
00238 at45d->cmdrsp[1] = page >> 5;
00239 at45d->cmdrsp[2] = (page << 3) | (pos >> 8);
00240 at45d->cmdrsp[3] = pos;
00241 at45d->cmdrsp[4] = 0;
00242 at45_write_cmd(at45d, 5);
00243 }
00244
00253 static inline void at45_cmd_buffer_1_write(struct at45_device *at45d, uint16_t pos)
00254 {
00255 assert(!(pos & ~AT45_PAGE_POS_MASK));
00256
00257 at45d->cmdrsp[0] = AT45_CMD_BUFFER_1_WRITE;
00258
00259
00260
00261 at45d->cmdrsp[2] = pos >> 8;
00262 at45d->cmdrsp[3] = pos;
00263 at45_write_cmd(at45d, 4);
00264 }
00265
00274 static inline void at45_cmd_main_memory_to_buffer_1_transfer(struct at45_device *at45d,
00275 uint16_t page)
00276 {
00277 assert(!(page & ~AT45_PAGE_ADDR_MASK));
00278
00279 at45d->cmdrsp[0] = AT45_CMD_MAIN_MEMORY_TO_BUFFER_1_TRANSFER;
00280
00281 at45d->cmdrsp[1] = page >> 5;
00282 at45d->cmdrsp[2] = page << 3;
00283 at45_write_cmd(at45d, 4);
00284 }
00285
00294 static inline void at45_cmd_buffer_1_main_memory_program_with_erase(
00295 struct at45_device *at45d, uint16_t page)
00296 {
00297 assert(!(page & ~AT45_PAGE_ADDR_MASK));
00298
00299 at45d->cmdrsp[0] = AT45_CMD_BUFFER_1_MAIN_MEMORY_PROGRAM_WITH_ERASE;
00300
00301 at45d->cmdrsp[1] = page >> 5;
00302 at45d->cmdrsp[2] = page << 3;
00303 at45_write_cmd(at45d, 4);
00304 }
00305
00314 static inline void at45_read_buf_list(struct at45_device *at45d,
00315 struct slist *buf_list)
00316 {
00317 spi_read_buf_list(at45d->spi_id, at45d->spim, buf_list);
00318 }
00319
00328 static inline void at45_write_buf_list(struct at45_device *at45d,
00329 struct slist *buf_list)
00330 {
00331 spi_write_buf_list(at45d->spi_id, at45d->spim, buf_list);
00332 }
00333
00341 static inline bool at45_rsp_status_is_ready(struct at45_device *at45d)
00342 {
00343 return at45d->cmdrsp[0] & (1 << AT45_STATUS_RDY);
00344 }
00345
00353 static inline bool at45_rsp_status_is_protected(struct at45_device *at45d)
00354 {
00355 return at45d->cmdrsp[0] & (1 << AT45_STATUS_PROTECT);
00356 }
00357
00358 bool at45_wait_ready(struct at45_device *at45d);
00359 bool at45_identify(struct at45_device *at45d);
00360 void at45_device_init(struct at45_device *at45d, spi_id_t spi_id,
00361 struct spi_master *spim, struct spi_device *spid);
00362
00364 #endif