Loading...
Searching...
No Matches
flash.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 "flash.h"
11
12/* SPI4 FLASH
13 * ---------------------------------------------
14 * Flash Pin | MCU GPIO Pin | SIGNAL TYPE
15 * ----------------|---------------|------------
16 * SDI | PE14 | DATA
17 * SDO | PE13 | DATA
18 * SCLK | PE12 | DATA
19 * CS | PE11 | CONTROL
20 * Memory Hold | PE10 | CONTROL
21 * Write Protect | PE9 | CONTROL */
22
23/* =============================================================================== */
34 Flash *flash,
35 char name[DEVICE_NAME_LENGTH],
36 GPIO_TypeDef *port,
37 unsigned long cs,
38 int pageSize,
39 long pageCount
40) {
41 SPI_init(&flash->base, MEMORY_FLASH, SPI4, MODE16, port, cs);
42 flash->pageSize = pageSize;
43 flash->pageCount = pageCount;
44 flash->erase = Flash_erase;
45 flash->readPage = Flash_readPage;
46 flash->writePage = Flash_writePage;
47
48 DeviceHandle_t handle;
49 strcpy(handle.name, name);
50 handle.device = flash;
51 return handle;
52}
53
54/********************************* PRIVATE METHODS *********************************/
55
56#ifndef DOXYGEN_PRIVATE
57
58/* =============================================================================== */
67 SPI spi = flash->base;
68
69 spi.port->ODR &= ~spi.cs;
70 spi.transmit(&spi, FLASH_WRITE_ENABLE);
71 spi.port->ODR |= spi.cs;
72}
73
74/* =============================================================================== */
83void _Flash_readStatus1(Flash *flash, uint8_t *status) {
84 SPI spi = flash->base;
85
86 spi.port->ODR &= ~spi.cs;
87 *status = spi.transmit(&spi, FLASH_READ_STATUS_REGISTER_1);
88 *status = spi.transmit(&spi, 0x0F);
89 spi.port->ODR |= spi.cs;
90}
91
92/* =============================================================================== */
101void _Flash_readStatus2(Flash *flash, uint8_t *status) {
102 SPI spi = flash->base;
103
104 spi.port->ODR &= ~spi.cs;
105 *status = spi.transmit(&spi, FLASH_READ_STATUS_REGISTER_2);
106 *status = spi.transmit(&spi, 0x0F);
107 spi.port->ODR |= spi.cs;
108}
109
110/* =============================================================================== */
119void _Flash_readStatus3(Flash *flash, uint8_t *status) {
120 SPI spi = flash->base;
121
122 spi.port->ODR &= ~spi.cs;
123 *status = spi.transmit(&spi, FLASH_READ_STATUS_REGISTER_3);
124 *status = spi.transmit(&spi, 0x0F);
125 spi.port->ODR |= spi.cs;
126}
127
128#endif
129
130/********************************* DEVICE METHODS **********************************/
131
132/* =============================================================================== */
140void Flash_erase(Flash *flash) {
141 _Flash_writeEnable(flash);
142 SPI spi = flash->base;
143 uint8_t status = 0;
144
145 // Send Erase Chip instruction
146 spi.port->ODR &= ~spi.cs;
147 spi.transmit(&spi, FLASH_ERASE_CHIP);
148 spi.port->ODR |= spi.cs;
149
150 // Wait until chip BUSY is clear
151 do {
152 _Flash_readStatus1(flash, &status);
153 } while (status & 0x01);
154}
155
156/* =============================================================================== */
166void Flash_writePage(Flash *flash, uint32_t address, uint8_t *data) {
167 _Flash_writeEnable(flash);
168 uint8_t status = 0;
169 SPI spi = flash->base;
170
171 spi.port->ODR &= ~spi.cs;
172
173 // Send Page Program instruction and 24-bit address
174 spi.transmit(&spi, FLASH_PAGE_PROGRAM);
175 spi.transmit(&spi, (address & 0xFF0000) >> 16);
176 spi.transmit(&spi, (address & 0xFF00) >> 8);
177 spi.transmit(&spi, (address & 0xFF));
178
179 // Send page data
180 for (int i = 0; i < 256; i++) {
181 spi.transmit(&spi, data[i]);
182 }
183
184 spi.port->ODR |= spi.cs;
185
186 // Wait until chip BUSY is clear
187 do {
188 _Flash_readStatus1(flash, &status);
189 } while (status & 0x1);
190}
191
192/* =============================================================================== */
202void Flash_readPage(Flash *flash, uint32_t address, volatile uint8_t *data) {
203 SPI spi = flash->base;
204
205 spi.port->ODR &= ~spi.cs;
206
207 // Send Read Data instruction and 24-bit address
208 spi.transmit(&spi, FLASH_READ_DATA);
209 spi.transmit(&spi, (address & 0xFF0000) >> 16);
210 spi.transmit(&spi, (address & 0xFF00) >> 8);
211 spi.transmit(&spi, (address & 0xFF));
212
213 for (int i = 0; i < 256; i++) {
214 data[i] = spi.transmit(&spi, 0x0F);
215 }
216
217 spi.port->ODR |= spi.cs;
218}
219
void _Flash_readStatus2(Flash *flash, uint8_t *status)
Read from Status Register 2.
Definition flash.c:101
void Flash_readPage(Flash *, uint32_t, volatile uint8_t *)
Read from flash.
Definition flash.c:202
void _Flash_readStatus1(Flash *flash, uint8_t *status)
Read from Status Register 1.
Definition flash.c:83
void _Flash_readStatus3(Flash *flash, uint8_t *status)
Read from Status Register 3.
Definition flash.c:119
void Flash_writePage(Flash *, uint32_t, uint8_t *)
Write page to flash.
Definition flash.c:166
DeviceHandle_t Flash_init(Flash *flash, char name[DEVICE_NAME_LENGTH], GPIO_TypeDef *port, unsigned long cs, int pageSize, long pageCount)
Initialise flash struct.
Definition flash.c:33
void _Flash_writeEnable(Flash *flash)
Send Write Enable instruction to the flash device.
Definition flash.c:66
void Flash_erase(Flash *)
Erase flash chip.
Definition flash.c:140
void SPI_init(SPI *, DeviceType, SPI_TypeDef *, DataFormat, GPIO_TypeDef *, unsigned long)
Initialiser for an SPI device interface.
Definition spi.c:32
@ MEMORY_FLASH
Flash memory.
Definition spi.h:32
Definition flash.h:30
Struct definition for SPI interface. Provides the interface for API consumers to interact with the SP...
Definition spi.h:49
uint16_t(* transmit)(struct SPI *, uint16_t)
SPI transmit method.
Definition spi.h:56
GPIO_TypeDef * port
Pointer to GPIO port struct.
Definition spi.h:52
unsigned long cs
Device chip select address.
Definition spi.h:53