30#define PX_AT25S_CMD_READ_ARRAY 0x03
35#define PX_AT25S_CMD_BLOCK_ERASE_4KB 0x20
36#define PX_AT25S_CMD_BLOCK_ERASE_32KB 0x52
37#define PX_AT25S_CMD_BLOCK_ERASE_64KB 0xd8
38#define PX_AT25S_CMD_CHIP_ERASE 0x60
39#define PX_AT25S_CMD_BYTE_PAGE_PROG 0x02
44#define PX_AT25S_CMD_WR_ENABLE 0x06
45#define PX_AT25S_CMD_WR_DISABLE 0x04
50#define PX_AT25S_CMD_RD_STATUS_REG_BYTE_1 0x05
51#define PX_AT25S_CMD_RD_STATUS_REG_BYTE_2 0x35
52#define PX_AT25S_CMD_WR_STATUS_REG 0x01
53#define PX_AT25S_CMD_WR_EN_VOL_STATUS_REG 0x50
58#define PX_AT25S_CMD_RD_MAN_AND_DEVICE_ID 0x9f
59#define PX_AT25S_CMD_RD_ID 0x90
60#define PX_AT25S_CMD_DEEP_PWR_DN 0xb9
61#define PX_AT25S_CMD_RESUME_FROM_DEEP_PWR_DN 0xab
69static bool px_at25s_ready_flag;
75static void px_at25s_tx_adr(uint32_t adr)
83 px_spi_wr(px_at25s_spi_handle, data, 3, 0);
86static void px_at25s_write_enable(
void)
90 data[0] = PX_AT25S_CMD_WR_ENABLE;
98 px_at25s_ready_flag =
true;
100 px_at25s_spi_handle = handle;
107 data[0] = PX_AT25S_CMD_DEEP_PWR_DN;
115 data[0] = PX_AT25S_CMD_RESUME_FROM_DEEP_PWR_DN;
128 data[0] = PX_AT25S_CMD_READ_ARRAY;
131 px_at25s_tx_adr(adr);
143 uint8_t start_byte_in_page,
144 uint16_t nr_of_bytes)
156 px_at25s_write_enable();
158 data[0] = PX_AT25S_CMD_BYTE_PAGE_PROG;
165 px_at25s_ready_flag =
false;
170 uint8_t start_byte_in_page,
171 uint16_t nr_of_bytes)
178 px_at25s_write_enable();
180 data[0] = PX_AT25S_CMD_BYTE_PAGE_PROG;
187 px_at25s_ready_flag =
false;
198 px_at25s_write_enable();
202 case PX_AT25S_BLOCK_4KB:
203 data[0] = PX_AT25S_CMD_BLOCK_ERASE_4KB;
204 if(page % PX_AT25S_PAGES_PER_BLOCK_4KB != 0)
206 PX_LOG_E(
"page nr %u is not on a erase block boundary", page);
209 case PX_AT25S_BLOCK_32KB:
210 data[0] = PX_AT25S_CMD_BLOCK_ERASE_32KB;
211 if(page % PX_AT25S_PAGES_PER_BLOCK_32KB != 0)
213 PX_LOG_E(
"page nr %u is not on a erase block boundary", page);
216 case PX_AT25S_BLOCK_64KB :
217 data[0] = PX_AT25S_CMD_BLOCK_ERASE_64KB;
218 if(page % PX_AT25S_PAGES_PER_BLOCK_64KB != 0)
220 PX_LOG_E(
"page nr %u is not on a erase block boundary", page);
224 PX_LOG_E(
"Invalid block size specified");
232 px_at25s_tx_adr(adr);
236 px_at25s_ready_flag =
false;
239void px_at25s_erase_chip(
void)
246 px_at25s_write_enable();
248 data[0] = PX_AT25S_CMD_CHIP_ERASE;
251 px_at25s_ready_flag =
false;
259 if(px_at25s_ready_flag)
269 px_at25s_ready_flag =
true;
283 data[0] = PX_AT25S_CMD_RD_STATUS_REG_BYTE_1;
296 data[0] = PX_AT25S_CMD_RD_MAN_AND_DEVICE_ID;
void px_at25s_rd_man_and_dev_id(uint8_t *buf)
Read Manufacturer and Device ID.
px_at25s_block_t
AT25S block selection.
void px_at25s_init(px_spi_handle_t *handle)
Initialise driver.
void px_at25s_wr_page_offset(const void *buf, uint16_t page, uint8_t start_byte_in_page, uint16_t nr_of_bytes)
Partial write of data in a page of Serial Flash.
#define PX_AT25S_PAGE_SIZE
AT25S page size.
void px_at25s_rd_page(void *buf, uint16_t page)
Read a page from Serial Flash.
void px_at25s_resume_from_deep_power_down(void)
Power up device to resume communication.
void px_at25s_rd(void *buf, uint32_t adr, uint16_t nr_of_bytes)
Read data from Serial Flash.
void px_at25s_wr_page(const void *buf, uint16_t page)
Write a page from Serial Flash.
uint8_t px_at25s_rd_status_reg1(void)
Read status register 1 of the Serial Flash.
#define PX_AT25S_STATUS_REG1_BSY
Ready/Busy Status.
bool px_at25s_ready(void)
Check if Serial Flash is ready for the next read or write access.
void px_at25s_erase(px_at25s_block_t block, uint16_t page)
Erase a block of Serial Flash.
#define PX_AT25S_ADR_MAX
Maximum address.
void px_at25s_rd_page_offset(void *buf, uint16_t page, uint8_t start_byte_in_page, uint16_t nr_of_bytes)
Partial read of data in a page of Serial Flash.
void px_at25s_deep_power_down(void)
Power down device to minimise power consumption.
#define NULL
NULL pointer.
#define PX_U32_LO8(data)
Extract the low 8 bits (bits 7..0) of a 32-bit value.
#define PX_BIT_IS_LO(var, bit)
Test if a bit is cleared (0?)
#define PX_U32_MH8(data)
Extract the middle high 8 bits (bits 23..16) of a 32-bit value.
#define PX_U32_ML8(data)
Extract the middle low 8 bits (bits 15..8) of a 32-bit value.
#define PX_LOG_NAME(name)
Macro to declare a log name string once for each file to reduce code size.
#define PX_LOG_E(format,...)
Macro to display a formatted ERROR message.
#define PX_LOG_ASSERT(expression)
Macro that will test an expression, and block indefinitely if false.
#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)