27#define PX_AT45D_CMD_CONTINUOUS_ARRAY_READ 0xe8
28#define PX_AT45D_CMD_MAIN_MEMORY_PAGE_READ 0xd2
29#define PX_AT45D_CMD_STATUS_REGISTER_READ 0xd7
34#define PX_AT45D_CMD_BUFFER1_WRITE 0x84
35#define PX_AT45D_CMD_BUFFER2_WRITE 0x87
37#define PX_AT45D_CMD_BUF1_TO_MAIN_PAGE_PRG_W_ERASE 0x83
38#define PX_AT45D_CMD_BUF2_TO_MAIN_PAGE_PRG_W_ERASE 0x86
40#define PX_AT45D_CMD_BUF1_TO_MAIN_PAGE_PRG_WO_ERASE 0x88
41#define PX_AT45D_CMD_BUF2_TO_MAIN_PAGE_PRG_WO_ERASE 0x89
43#define PX_AT45D_CMD_MAIN_MEM_PROG_THROUGH_BUF1 0x82
44#define PX_AT45D_CMD_MAIN_MEM_PROG_THROUGH_BUF2 0x85
46#define PX_AT45D_CMD_PAGE_ERASE 0x81
51#define PX_AT45D_CMD_MAIN_MEM_PAGE_TO_BUF1 0x53
52#define PX_AT45D_CMD_MAIN_MEM_PAGE_TO_BUF2 0x55
55#define PX_AT45D_CMD_MAIN_DEEP_PWR_DN 0xb9
56#define PX_AT45D_CMD_MAIN_RESUME_FROM_DEEP_PWR_DN 0xab
57#define PX_AT45D_CMD_MAIN_ULTRA_DEEP_PWR_DN 0x79
65static bool px_at45d_ready_flag;
71#if ((PX_AT45D_PAGE_SIZE != 256) && (PX_AT45D_PAGE_SIZE != 264))
72#error "This driver does not work for any other page size yet. See comment!"
81static void px_at45d_tx_adr(uint16_t page, uint16_t start_byte_in_page)
85#if PX_VAL_IS_PWR_OF_TWO(PX_AT45D_PAGE_SIZE)
86 data[0] = (uint8_t)(page >> 8) & 0xFF;
87 data[1] = (uint8_t)(page & 0xFF);
88 data[2] = (uint8_t)(start_byte_in_page & 0xFF);
90 data[0] = (page >> 7) & 0xFF;
91 data[1] = ((page << 1) | (start_byte_in_page >> 8)) & 0xFF;
92 data[2] = start_byte_in_page & 0xFF;
95 px_spi_wr(px_at45d_spi_handle, data, 3, 0);
102 px_at45d_ready_flag =
true;
104 px_at45d_spi_handle = handle;
111 data[0] = PX_AT45D_CMD_MAIN_DEEP_PWR_DN;
119 data[0] = PX_AT45D_CMD_MAIN_RESUME_FROM_DEEP_PWR_DN;
127 data[0] = PX_AT45D_CMD_MAIN_ULTRA_DEEP_PWR_DN;
143 uint16_t start_byte_in_page;
153 if(nr_of_bytes > max_bytes_to_read)
155 nr_of_bytes = max_bytes_to_read;
160 data[0] = PX_AT45D_CMD_CONTINUOUS_ARRAY_READ;
163#if PX_VAL_IS_PWR_OF_TWO(PX_AT45D_PAGE_SIZE)
165 start_byte_in_page = adr & 0xff;
167 page = adr / PX_AT45D_PAGE_SIZE;
168 start_byte_in_page = adr % PX_AT45D_PAGE_SIZE;
171 px_at45d_tx_adr(page, start_byte_in_page);
177 px_spi_wr(px_at45d_spi_handle, data, 4, 0);
191 data[0] = PX_AT45D_CMD_MAIN_MEMORY_PAGE_READ;
194 px_at45d_tx_adr(page, 0);
200 px_spi_wr(px_at45d_spi_handle, data, 4, 0);
207 uint16_t start_byte_in_page,
208 uint16_t nr_of_bytes)
215 data[0] = PX_AT45D_CMD_CONTINUOUS_ARRAY_READ;
218 px_at45d_tx_adr(page, start_byte_in_page);
224 px_spi_wr(px_at45d_spi_handle, data, 4, 0);
236 data[0] = PX_AT45D_CMD_MAIN_MEM_PROG_THROUGH_BUF1;
239 px_at45d_tx_adr(page, 0);
243 px_at45d_ready_flag =
false;
248 uint16_t start_byte_in_page,
249 uint16_t nr_of_bytes)
252 uint8_t * buf_u8 = (uint8_t *)buf;
258 data[0] = PX_AT45D_CMD_BUFFER1_WRITE;
264 px_spi_wr(px_at45d_spi_handle, data, 3, 0);
266 for(i = 0; i < PX_AT45D_PAGE_SIZE; i++)
268 if((i >= start_byte_in_page) && (i < (start_byte_in_page + nr_of_bytes)))
270 px_spi_wr(px_at45d_spi_handle, buf_u8++, 1, 0);
276 px_spi_wr(px_at45d_spi_handle, data, 1, 0);
282 px_at45d_ready_flag =
false;
286 data[0] = PX_AT45D_CMD_BUF1_TO_MAIN_PAGE_PRG_WO_ERASE;
289 px_at45d_tx_adr(page, 0);
293 px_at45d_ready_flag =
false;
303 data[0] = PX_AT45D_CMD_PAGE_ERASE;
306 px_at45d_tx_adr(page, 0);
310 px_at45d_ready_flag =
false;
318 if(px_at45d_ready_flag)
328 px_at45d_ready_flag =
true;
342 data[0] = PX_AT45D_CMD_STATUS_REGISTER_READ;
void px_at45d_rd_page_offset(void *buf, uint16_t page, uint16_t start_byte_in_page, uint16_t nr_of_bytes)
Partial read of data in a page of DataFlash.
uint8_t px_at45d_get_status(void)
Read the status register of the DataFlash.
bool px_at45d_ready(void)
Check if DataFlash is ready for the next read or write access.
#define PX_AT45D_STATUS_READY
Ready flag.
void px_at45d_wr_page(const void *buf, uint16_t page)
Write a page from DataFlash.
uint16_t px_at45d_rd(void *buf, px_at45d_adr_t adr, uint16_t nr_of_bytes)
Read data from DataFlash.
void px_at45d_resume_from_deep_power_down(void)
Power up device to resume communication.
bool px_at45d_set_page_size_to_pwr_of_two(void)
Sets the page size of the DataFlash to a power of two.
#define PX_AT45D_ADR_MAX
Maximum adress.
void px_at45d_erase(uint16_t page)
Erase a page of DataFlash.
void px_at45d_deep_power_down(void)
Power down device to minimise power consumption.
#define PX_AT45D_STATUS_PAGE_SIZE
Page size flag.
void px_at45d_ultra_deep_power_down(void)
Power down device to minimise power consumption.
void px_at45d_wr_page_offset(const void *buf, uint16_t page, uint16_t start_byte_in_page, uint16_t nr_of_bytes)
Partial write of data in a page of DataFlash.
uint32_t px_at45d_adr_t
Address size can be optimized, depending on maximum size of FLASH.
void px_at45d_init(px_spi_handle_t *handle)
Initialise driver.
bool px_at45d_page_size_is_pwr_of_two(void)
Check if page size of the DataFlash is a power of two.
void px_at45d_rd_page(void *buf, uint16_t page)
Read a page from DataFlash.
void px_at45d_resume_from_ultra_deep_power_down(void)
Power up device to resume communication.
#define NULL
NULL pointer.
#define PX_BIT_IS_HI(var, bit)
Test if a bit is set (1?)
#define PX_SPI_FLAG_START_AND_STOP
Begin and finish SPI transaction.
#define PX_SPI_FLAG_START
Begin SPI transaction (take SPI slave's Chip Select line low)
void px_spi_wr(px_spi_handle_t *handle, const void *data, size_t nr_of_bytes, uint8_t flags)
Perform an SPI write transaction with an SPI slave.
void px_spi_rd(px_spi_handle_t *handle, void *data, size_t nr_of_bytes, uint8_t flags)
Perform an SPI read transaction with an SPI slave.
#define PX_SPI_FLAG_STOP
Finish SPI transaction (take SPI slave's Chip Select line high)