Loading...
Searching...
No Matches
w25q128.c
1/***********************************************************************************
2 * @file flash.c *
3 * @author Matt Ricci *
4 * @addtogroup Flash *
5 * @brief Brief description of the file's purpose. *
6 * *
7 * @{ *
8 ***********************************************************************************/
9
10#include "w25q128.h"
11
12/* =============================================================================== */
23 W25Q128_t *flash,
24 SPI_t *spi,
25 GPIOpin_t cs
26) {
27 flash->spi = spi;
28 flash->cs = cs;
29 flash->base.pageSize = W25Q128_PAGE_SIZE;
30 flash->base.pageCount = W25Q128_PAGE_COUNT;
31 flash->base.erase = W25Q128_erase;
32 flash->base.readPage = W25Q128_readPage;
33 flash->base.writePage = W25Q128_writePage;
34
35 return *flash;
36}
37
38/********************************* PRIVATE METHODS *********************************/
39
40// ALLOW FORMATTING
41#ifndef __DOXYGEN__
42
43/* =============================================================================== */
51void _W25Q128_writeEnable(W25Q128_t *flash) {
52 SPI_t *spi = flash->spi;
53 GPIOpin_t cs = flash->cs;
54
55 cs.reset(&cs);
56 spi->transmit(spi, W25Q128_WRITE_ENABLE);
57 cs.set(&cs);
58}
59
60/* =============================================================================== */
69void _W25Q128_readStatus1(W25Q128_t *flash, uint8_t *status) {
70 SPI_t *spi = flash->spi;
71 GPIOpin_t cs = flash->cs;
72
73 cs.reset(&cs);
74 *status = spi->transmit(spi, W25Q128_READ_STATUS_REGISTER_1);
75 *status = spi->transmit(spi, 0x0F);
76 cs.set(&cs);
77}
78
79/* =============================================================================== */
88void _W25Q128_readStatus2(W25Q128_t *flash, uint8_t *status) {
89 SPI_t *spi = flash->spi;
90 GPIOpin_t cs = flash->cs;
91
92 cs.reset(&cs);
93 *status = spi->transmit(spi, W25Q128_READ_STATUS_REGISTER_2);
94 *status = spi->transmit(spi, 0x0F);
95 cs.set(&cs);
96}
97
98/* =============================================================================== */
107void _W25Q128_readStatus3(W25Q128_t *flash, uint8_t *status) {
108 SPI_t *spi = flash->spi;
109 GPIOpin_t cs = flash->cs;
110
111 cs.reset(&cs);
112 *status = spi->transmit(spi, W25Q128_READ_STATUS_REGISTER_3);
113 *status = spi->transmit(spi, 0x0F);
114 cs.set(&cs);
115}
116
117#endif
118
119/******************************** DEVICE API METHODS *******************************/
120
121/* =============================================================================== */
129void W25Q128_erase(Flash_t *flash) {
130 W25Q128_t *driver = (W25Q128_t *)flash;
131 _W25Q128_writeEnable(driver);
132 SPI_t *spi = driver->spi;
133 GPIOpin_t cs = driver->cs;
134
135 uint8_t status = 0;
136
137 // Send Erase Chip instruction
138 cs.reset(&cs);
139 spi->transmit(spi, W25Q128_ERASE_CHIP);
140 cs.set(&cs);
141
142 // Wait until chip BUSY is clear
143 do {
144 _W25Q128_readStatus1(driver, &status);
145 } while (status & 0x01);
146}
147
148/* =============================================================================== */
158void W25Q128_writePage(Flash_t *flash, uint32_t address, uint8_t *data) {
159 W25Q128_t *driver = (W25Q128_t *)flash;
160 _W25Q128_writeEnable(driver);
161 SPI_t *spi = driver->spi;
162 GPIOpin_t cs = driver->cs;
163
164 uint8_t status = 0;
165
166 cs.reset(&cs);
167
168 // Send Page Program instruction and 24-bit address
169 spi->transmit(spi, W25Q128_PAGE_PROGRAM);
170 spi->transmit(spi, (address & 0xFF0000) >> 16);
171 spi->transmit(spi, (address & 0xFF00) >> 8);
172 spi->transmit(spi, (address & 0xFF));
173
174 // Send page data
175 for (int i = 0; i < 256; i++) {
176 spi->transmit(spi, data[i]);
177 }
178
179 cs.set(&cs);
180
181 // Wait until chip BUSY is clear
182 do {
183 _W25Q128_readStatus1(driver, &status);
184 } while (status & 0x1);
185}
186
187/* =============================================================================== */
197void W25Q128_readPage(Flash_t *flash, uint32_t address, volatile uint8_t *data) {
198 W25Q128_t *driver = (W25Q128_t *)flash;
199 SPI_t *spi = driver->spi;
200 GPIOpin_t cs = driver->cs;
201
202 cs.reset(&cs);
203
204 // Send Read Data instruction and 24-bit address
205 spi->transmit(spi, W25Q128_READ_DATA);
206 spi->transmit(spi, (address & 0xFF0000) >> 16);
207 spi->transmit(spi, (address & 0xFF00) >> 8);
208 spi->transmit(spi, (address & 0xFF));
209
210 for (int i = 0; i < 256; i++) {
211 data[i] = spi->transmit(spi, 0x0F);
212 }
213
214 cs.set(&cs);
215}
216
int pageSize
Number of bytes per page.
Definition flash.h:22
long pageCount
Total number of pages.
Definition flash.h:23
void(* readPage)(struct Flash *, uint32_t, volatile uint8_t *)
Read page method.
Definition flash.h:25
void(* erase)(struct Flash *)
Chip erase method.
Definition flash.h:24
void(* writePage)(struct Flash *, uint32_t, uint8_t *)
Write page method.
Definition flash.h:26
GPIOpin_t cs
Chip select GPIO.
Definition w25q128.h:36
SPI_t * spi
Parent SPI interface.
Definition w25q128.h:35
void(* set)(struct GPIOpin *)
Definition gpiopin.h:155
void(* reset)(struct GPIOpin *)
Definition gpiopin.h:156
Struct definition for a GPIO pin.
Definition gpiopin.h:151
uint16_t(* transmit)(struct SPI *, uint16_t)
SPI transmit method.
Definition spi.h:139
Struct definition for SPI interface. Provides the interface for API consumers to interact with the SP...
Definition spi.h:134
void W25Q128_writePage(Flash_t *, uint32_t, uint8_t *)
Write page to flash.
Definition w25q128.c:158
void W25Q128_readPage(Flash_t *, uint32_t, volatile uint8_t *)
Read from flash.
Definition w25q128.c:197
W25Q128_t W25Q128_init(W25Q128_t *flash, SPI_t *spi, GPIOpin_t cs)
Initialise flash struct.
Definition w25q128.c:22
void W25Q128_erase(Flash_t *)
Erase flash chip.
Definition w25q128.c:129