1 /*
2 * Copyright (c) 2023 Arm Limited
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #ifndef __DRIVER_FLASH_N25Q256A_H__
18 #define __DRIVER_FLASH_N25Q256A_H__
19
20 #include "Driver_Flash_Common.h"
21 #include "spi_n25q256a_flash_lib.h"
22
23 /*
24 * ARM FLASH device structure
25 */
26 struct arm_n25q256a_flash_dev_t {
27 struct spi_n25q256a_dev_t *dev; /*!< FLASH memory device structure */
28 ARM_FLASH_INFO *data; /*!< FLASH data */
29 };
30
31 /* Driver Capabilities */
32 static const ARM_FLASH_CAPABILITIES N25Q256ADriverCapabilities = {
33 0, /* event_ready */
34 0, /* data_width = 0:8-bit, 1:16-bit, 2:32-bit */
35 1 /* erase_chip */
36 };
37
38 static ARM_FLASH_INFO N25Q256A_DEV_DATA = {
39 .sector_info = NULL, /* Uniform sector layout */
40 .sector_count = PMOD_SF3_FLASH_TOTAL_SIZE / PMOD_SF3_FLASH_SECTOR_SIZE,
41 .sector_size = PMOD_SF3_FLASH_SECTOR_SIZE,
42 .page_size = PMOD_SF3_FLASH_PAGE_SIZE,
43 .program_unit = PMOD_SF3_FLASH_PROGRAM_UNIT,
44 .erased_value = ARM_FLASH_DRV_ERASE_VALUE
45 };
46
N25Q256A_Driver_GetCapabilities(void)47 static inline ARM_FLASH_CAPABILITIES N25Q256A_Driver_GetCapabilities(void)
48 {
49 return N25Q256ADriverCapabilities;
50 }
51
52 /*
53 * \brief Macro for N25Q256A Flash Driver
54 *
55 * \param[in] FLASH_DEV Native driver device
56 * \ref arm_n25q256a_flash_dev_t
57 * \param[out] FLASH_DRIVER_NAME Resulting Driver name
58 */
59 #define ARM_FLASH_N25Q256A(FLASH_DEV, FLASH_DRIVER_NAME) \
60 static int32_t FLASH_DRIVER_NAME##_Initialize( \
61 ARM_Flash_SignalEvent_t cb_event) \
62 { \
63 ARG_UNUSED(cb_event); \
64 enum n25q256a_error_t ret; \
65 struct spi_n25q256a_dev_t* dev = FLASH_DEV.dev; \
66 ARM_FLASH_INFO* data = FLASH_DEV.data; \
67 \
68 dev->total_sector_cnt = data->sector_count; \
69 dev->page_size = data->page_size; \
70 dev->sector_size = data->sector_size; \
71 dev->program_unit = data->program_unit; \
72 \
73 ret = spi_n25q256a_initialize(FLASH_DEV.dev); \
74 if (ret != N25Q256A_ERR_NONE) { \
75 SPI_FLASH_LOG_MSG("%s: Initialization failed.\n\r", __func__); \
76 return ARM_DRIVER_ERROR; \
77 } \
78 \
79 return ARM_DRIVER_OK; \
80 } \
81 \
82 static int32_t FLASH_DRIVER_NAME##_Uninitialize(void) \
83 { \
84 spi_n25q256a_uninitialize(FLASH_DEV.dev); \
85 return ARM_DRIVER_OK; \
86 } \
87 \
88 static int32_t FLASH_DRIVER_NAME##_ReadData(uint32_t addr, \
89 void *data, \
90 uint32_t cnt) \
91 { \
92 enum n25q256a_error_t ret; \
93 \
94 if (N25Q256ADriverCapabilities.data_width > 2 || \
95 N25Q256ADriverCapabilities.data_width < 0) \
96 { \
97 SPI_FLASH_LOG_MSG("%s: Incorrect data width selected: addr=0x%x\n\r", \
98 __func__, \
99 addr); \
100 return ARM_DRIVER_ERROR; \
101 } \
102 \
103 cnt *= data_width_byte[N25Q256ADriverCapabilities.data_width]; \
104 \
105 ret = spi_n25q256a_read(FLASH_DEV.dev, addr, (uint8_t*) data, cnt); \
106 if (ret != N25Q256A_ERR_NONE) { \
107 SPI_FLASH_LOG_MSG("%s: read failed: addr=0x%x, cnt=%u\n\r", \
108 __func__, \
109 addr, \
110 cnt); \
111 return ARM_DRIVER_ERROR; \
112 } \
113 \
114 cnt /= data_width_byte[N25Q256ADriverCapabilities.data_width]; \
115 \
116 return cnt; \
117 } \
118 \
119 static int32_t FLASH_DRIVER_NAME##_ProgramData(uint32_t addr, \
120 const void *data, \
121 uint32_t cnt) \
122 { \
123 enum n25q256a_error_t ret; \
124 \
125 if (N25Q256ADriverCapabilities.data_width > 2 || \
126 N25Q256ADriverCapabilities.data_width < 0) \
127 { \
128 SPI_FLASH_LOG_MSG("%s: Incorrect data width selected: addr=0x%x\n\r", \
129 __func__, \
130 addr); \
131 return ARM_DRIVER_ERROR; \
132 } \
133 \
134 cnt *= data_width_byte[N25Q256ADriverCapabilities.data_width]; \
135 \
136 ret = spi_n25q256a_program(FLASH_DEV.dev, addr, (uint8_t*) data, cnt); \
137 if (ret != N25Q256A_ERR_NONE) { \
138 SPI_FLASH_LOG_MSG("%s: program failed: addr=0x%x, cnt=%u\n\r", \
139 __func__, \
140 addr, \
141 cnt); \
142 return ARM_DRIVER_ERROR; \
143 } \
144 \
145 cnt /= data_width_byte[N25Q256ADriverCapabilities.data_width]; \
146 \
147 return cnt; \
148 } \
149 \
150 static int32_t FLASH_DRIVER_NAME##_EraseSector(uint32_t addr) \
151 { \
152 enum n25q256a_error_t ret; \
153 \
154 ret = spi_n25q256a_erase(FLASH_DEV.dev, addr); \
155 if (ret != N25Q256A_ERR_NONE) { \
156 SPI_FLASH_LOG_MSG("%s: erase failed: addr=0x%x\n\r", __func__, addr); \
157 return ARM_DRIVER_ERROR; \
158 } \
159 \
160 return ARM_DRIVER_OK; \
161 } \
162 \
163 static int32_t FLASH_DRIVER_NAME##_EraseChip(void) \
164 { \
165 enum n25q256a_error_t ret; \
166 \
167 ret = spi_n25q256a_erase_chip(FLASH_DEV.dev); \
168 if (ret != N25Q256A_ERR_NONE) { \
169 SPI_FLASH_LOG_MSG("%s: erase chip failed\n\r", __func__); \
170 return ARM_DRIVER_ERROR; \
171 } \
172 \
173 return ARM_DRIVER_OK; \
174 } \
175 \
176 static ARM_FLASH_INFO * FLASH_DRIVER_NAME##_GetInfo(void) \
177 { \
178 return FLASH_DEV.data; \
179 } \
180 \
181 ARM_DRIVER_FLASH FLASH_DRIVER_NAME = { \
182 ARM_Flash_GetVersion, \
183 N25Q256A_Driver_GetCapabilities, \
184 FLASH_DRIVER_NAME##_Initialize, \
185 FLASH_DRIVER_NAME##_Uninitialize, \
186 ARM_Flash_PowerControl, \
187 FLASH_DRIVER_NAME##_ReadData, \
188 FLASH_DRIVER_NAME##_ProgramData, \
189 FLASH_DRIVER_NAME##_EraseSector, \
190 FLASH_DRIVER_NAME##_EraseChip, \
191 ARM_Flash_GetStatus, \
192 FLASH_DRIVER_NAME##_GetInfo \
193 }
194
195 #endif /* __DRIVER_FLASH_N25Q256A_H__ */
196