1 /*
2  * Copyright (c) 2013-2018 Arm Limited. All rights reserved.
3  * Copyright (c) 2021 Laird Connectivity. All rights reserved.
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  *
7  * Licensed under the Apache License, Version 2.0 (the License); you may
8  * not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an AS IS BASIS, WITHOUT
15  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 
20 #include <Driver_Flash.h>
21 #include <RTE_Device.h>
22 #include <flash_layout.h>
23 #include <string.h>
24 #include <nrfx_qspi.h>
25 
26 #ifndef ARG_UNUSED
27 #define ARG_UNUSED(arg)  (void)arg
28 #endif
29 
30 #define ARM_FLASH_DRV_VERSION    ARM_DRIVER_VERSION_MAJOR_MINOR(1, 0)
31 #define QSPI_MIN_READ_SIZE       4
32 #define QSPI_READ_SIZE_ALIGNMENT 4
33 #define QSPI_READ_BUFFER_SIZE    512
34 
35 #if RTE_QSPI0
36 
37 /**
38  * Data width values for ARM_FLASH_CAPABILITIES::data_width
39  * \ref ARM_FLASH_CAPABILITIES
40  */
41 enum {
42     DATA_WIDTH_8BIT = 0u,
43     DATA_WIDTH_16BIT,
44     DATA_WIDTH_32BIT,
45     DATA_WIDTH_ENUM_SIZE
46 };
47 
48 static const uint32_t data_width_byte[DATA_WIDTH_ENUM_SIZE] = {
49     sizeof(uint8_t),
50     sizeof(uint16_t),
51     sizeof(uint32_t),
52 };
53 
54 static const ARM_DRIVER_VERSION DriverVersion = {
55     ARM_FLASH_API_VERSION,
56     ARM_FLASH_DRV_VERSION
57 };
58 
59 static const ARM_FLASH_CAPABILITIES DriverCapabilities = {
60     .event_ready = 0,
61     .data_width  = DATA_WIDTH_32BIT,
62     .erase_chip  = 0
63 };
64 
65 static ARM_FLASH_INFO FlashInfo = {
66     .sector_info  = NULL, /* Uniform sector layout */
67     .sector_count = QSPI_FLASH_TOTAL_SIZE / QSPI_FLASH_AREA_IMAGE_SECTOR_SIZE,
68     .sector_size  = QSPI_FLASH_AREA_IMAGE_SECTOR_SIZE,
69     .page_size    = 256,
70     .program_unit = sizeof(uint32_t), /* 32-bit word = 4 bytes */
71     .erased_value = 0xFF
72 };
73 
74 static const nrfx_qspi_config_t pQSPIConf = NRFX_QSPI_DEFAULT_CONFIG(RTE_QSPI0_SCL_PIN,
75                                                                      RTE_QSPI0_CSN_PIN,
76                                                                      RTE_QSPI0_IO0_PIN,
77                                                                      RTE_QSPI0_IO1_PIN,
78                                                                      RTE_QSPI0_IO2_PIN,
79                                                                      RTE_QSPI0_IO3_PIN);
80 
81 static bool bQSPIInit = false;
82 
83 __ALIGN(4) uint8_t baTmpRAMBuffer[QSPI_READ_BUFFER_SIZE];
84 
is_range_valid(uint32_t addr,uint32_t cnt)85 static bool is_range_valid(uint32_t addr, uint32_t cnt)
86 {
87     if (addr > QSPI_FLASH_TOTAL_SIZE) {
88         return false;
89     }
90 
91     if (cnt > (QSPI_FLASH_TOTAL_SIZE - addr)) {
92         return false;
93     }
94 
95     return true;
96 }
97 
ARM_QSPI_Flash_GetVersion(void)98 static ARM_DRIVER_VERSION ARM_QSPI_Flash_GetVersion(void)
99 {
100     return DriverVersion;
101 }
102 
ARM_QSPI_Flash_GetCapabilities(void)103 static ARM_FLASH_CAPABILITIES ARM_QSPI_Flash_GetCapabilities(void)
104 {
105     return DriverCapabilities;
106 }
107 
ARM_QSPI_Flash_Initialize(ARM_Flash_SignalEvent_t cb_event)108 static int32_t ARM_QSPI_Flash_Initialize(ARM_Flash_SignalEvent_t cb_event)
109 {
110     ARG_UNUSED(cb_event);
111 
112     if (bQSPIInit == false)
113     {
114         if (nrfx_qspi_init(&pQSPIConf, NULL, NULL) != NRFX_SUCCESS)
115         {
116             return ARM_DRIVER_ERROR_PARAMETER;
117         }
118 
119         bQSPIInit = true;
120     }
121 
122     return ARM_DRIVER_OK;
123 }
124 
ARM_QSPI_Flash_Uninitialize(void)125 static int32_t ARM_QSPI_Flash_Uninitialize(void)
126 {
127     if (bQSPIInit == true)
128     {
129         nrfx_qspi_uninit();
130         bQSPIInit = false;
131     }
132 
133     /* Clear the QSPI read buffer to prevent information leakage */
134     memset(baTmpRAMBuffer, 0, sizeof(baTmpRAMBuffer));
135 
136     return ARM_DRIVER_OK;
137 }
138 
ARM_QSPI_Flash_PowerControl(ARM_POWER_STATE state)139 static int32_t ARM_QSPI_Flash_PowerControl(ARM_POWER_STATE state)
140 {
141     switch (state) {
142     case ARM_POWER_FULL:
143         /* Nothing to be done */
144         return ARM_DRIVER_OK;
145 
146     case ARM_POWER_OFF:
147     case ARM_POWER_LOW:
148     default:
149         return ARM_DRIVER_ERROR_UNSUPPORTED;
150     }
151 }
152 
ARM_QSPI_Flash_ReadData(uint32_t addr,void * data,uint32_t cnt)153 static int32_t ARM_QSPI_Flash_ReadData(uint32_t addr, void *data, uint32_t cnt)
154 {
155     uint32_t data_index = 0;
156     uint8_t *buffer = (uint8_t *)data;
157 
158     /* Conversion between data items and bytes */
159     uint32_t bytes = cnt * data_width_byte[DriverCapabilities.data_width];
160 
161     if ((addr % QSPI_READ_SIZE_ALIGNMENT) != 0)
162     {
163         /* Read beginning part prior to requested data which is before the word boundary */
164         uint8_t off_by = (addr % QSPI_READ_SIZE_ALIGNMENT);
165         uint8_t needed = QSPI_READ_SIZE_ALIGNMENT - off_by;
166         uint32_t read_pos = addr - off_by;
167 
168         if (nrfx_qspi_read(baTmpRAMBuffer, QSPI_MIN_READ_SIZE, read_pos) != NRFX_SUCCESS)
169         {
170              return ARM_DRIVER_ERROR_PARAMETER;
171         }
172 
173         memcpy(&buffer[data_index], &baTmpRAMBuffer[off_by], needed);
174         data_index += needed;
175         addr += needed;
176         bytes -= needed;
177     }
178 
179     while (bytes > 0)
180     {
181         /* Read in chunks of data to the temporary buffer and copy to the supplied buffer */
182         uint32_t read_size = sizeof(baTmpRAMBuffer);
183         uint32_t save_size = read_size;
184         if (bytes < read_size)
185         {
186             read_size = bytes;
187             save_size = bytes;
188 
189             if ((read_size % QSPI_READ_SIZE_ALIGNMENT) != 0)
190             {
191                 /* Ensure read size is a multiple of the word size */
192                 read_size += QSPI_READ_SIZE_ALIGNMENT - (read_size % QSPI_READ_SIZE_ALIGNMENT);
193             }
194         }
195 
196         if (nrfx_qspi_read(baTmpRAMBuffer, read_size, addr) != NRFX_SUCCESS)
197         {
198             return ARM_DRIVER_ERROR_PARAMETER;
199         }
200 
201         memcpy(&buffer[data_index], baTmpRAMBuffer, save_size);
202         data_index += save_size;
203         addr += save_size;
204         bytes -= save_size;
205     }
206 
207     return cnt;
208 }
209 
ARM_QSPI_Flash_ProgramData(uint32_t addr,const void * data,uint32_t cnt)210 static int32_t ARM_QSPI_Flash_ProgramData(uint32_t addr, const void *data,
211                                           uint32_t cnt)
212 {
213     uint32_t err;
214 
215     /* Conversion between data items and bytes */
216     uint32_t bytes = cnt * data_width_byte[DriverCapabilities.data_width];
217 
218     /* Only aligned writes of full 32-bit words are allowed. */
219     if (addr % sizeof(uint32_t)) {
220         return ARM_DRIVER_ERROR_PARAMETER;
221     }
222 
223     if (!is_range_valid(addr, bytes)) {
224         return ARM_DRIVER_ERROR_PARAMETER;
225     }
226 
227     if (!nrfx_is_in_ram(data))
228     {
229         /* Not in RAM, copy to RAM so it can be written to QSPI */
230         __ALIGN(4) uint8_t baRAMDataBuffer[bytes];
231         memcpy(baRAMDataBuffer, data, bytes);
232         err = nrfx_qspi_write(baRAMDataBuffer, bytes, addr);
233     }
234     else
235     {
236         err = nrfx_qspi_write(data, bytes, addr);
237     }
238 
239     if (err != NRFX_SUCCESS)
240     {
241         return ARM_DRIVER_ERROR;
242     }
243 
244     return cnt;
245 }
246 
ARM_QSPI_Flash_EraseSector(uint32_t addr)247 static int32_t ARM_QSPI_Flash_EraseSector(uint32_t addr)
248 {
249     nrfx_err_t err_code;
250 
251     if (!is_range_valid(addr, QSPI_FLASH_AREA_IMAGE_SECTOR_SIZE)) {
252         return ARM_DRIVER_ERROR_PARAMETER;
253     }
254 
255     err_code = nrfx_qspi_erase(NRF_QSPI_ERASE_LEN_4KB, addr);
256 
257     if (err_code != NRFX_SUCCESS) {
258         return ARM_DRIVER_ERROR;
259     }
260 
261     return ARM_DRIVER_OK;
262 }
263 
ARM_QSPI_Flash_EraseChip(void)264 static int32_t ARM_QSPI_Flash_EraseChip(void)
265 {
266     return ARM_DRIVER_ERROR_UNSUPPORTED;
267 }
268 
ARM_QSPI_Flash_GetStatus(void)269 static ARM_FLASH_STATUS ARM_QSPI_Flash_GetStatus(void)
270 {
271     ARM_FLASH_STATUS status = {
272         .busy = (nrfx_qspi_mem_busy_check() == NRFX_SUCCESS)
273     };
274 
275     return status;
276 }
277 
ARM_QSPI_Flash_GetInfo(void)278 static ARM_FLASH_INFO * ARM_QSPI_Flash_GetInfo(void)
279 {
280     return &FlashInfo;
281 }
282 
283 ARM_DRIVER_FLASH Driver_FLASH1 = {
284     .GetVersion      = ARM_QSPI_Flash_GetVersion,
285     .GetCapabilities = ARM_QSPI_Flash_GetCapabilities,
286     .Initialize      = ARM_QSPI_Flash_Initialize,
287     .Uninitialize    = ARM_QSPI_Flash_Uninitialize,
288     .PowerControl    = ARM_QSPI_Flash_PowerControl,
289     .ReadData        = ARM_QSPI_Flash_ReadData,
290     .ProgramData     = ARM_QSPI_Flash_ProgramData,
291     .EraseSector     = ARM_QSPI_Flash_EraseSector,
292     .EraseChip       = ARM_QSPI_Flash_EraseChip,
293     .GetStatus       = ARM_QSPI_Flash_GetStatus,
294     .GetInfo         = ARM_QSPI_Flash_GetInfo
295 };
296 
297 #endif /* RTE_QSPI0 */
298