1 /***************************************************************************//**
2 * \file cy_smif_hb_flash.c
3 * \version 2.100
4 *
5 * \brief
6 * This file provides the source code for the Hyper Bus APIs of the SMIF driver.
7 *
8 * Note:
9 *
10 ********************************************************************************
11 * \copyright
12 * Copyright 2021-2022 Cypress Semiconductor Corporation
13 * SPDX-License-Identifier: Apache-2.0
14 *
15 * Licensed under the Apache License, Version 2.0 (the "License");
16 * you may not use this file except in compliance with the License.
17 * You may obtain a copy of the License at
18 *
19 * http://www.apache.org/licenses/LICENSE-2.0
20 *
21 * Unless required by applicable law or agreed to in writing, software
22 * distributed under the License is distributed on an "AS IS" BASIS,
23 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
24 * See the License for the specific language governing permissions and
25 * limitations under the License.
26 *******************************************************************************/
27 #include "cy_device.h"
28
29 #if defined (CY_IP_MXSMIF) && (CY_IP_MXSMIF_VERSION>=2) && (CY_IP_MXSMIF_VERSION <= 5)
30 #ifdef __cplusplus
31 extern "C" {
32 #endif /* __cplusplus */
33 #include "cy_smif_memslot.h"
34 #include <string.h>
35
36
37 /*****************************************************************************
38 Pattern that should be used to calibrate the delay of RWDS capturing
39 *****************************************************************************/
40 /* Length of the calibration data pattern (Cy_SMIF_HB_CalibrationDataPattern) for HyperBus in bytes */
41 #define CY_SMIF_HB_CALIBRATION_DATA_PATTERN_LENGTH 12U
42 static uint8_t Cy_SMIF_HB_CalibrationDataPattern[CY_SMIF_HB_CALIBRATION_DATA_PATTERN_LENGTH] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11 };
43 #define DEVICEREADY_CHECK_TIMEOUT 100U
44 static uint16_t writeBuf = 0x0000U;
45
46 /* private functions */
47 static void Cy_SMIF_HB_SetDummyCycles(volatile SMIF_DEVICE_Type *dev, cy_en_smif_hb_dev_type_t hbDevType, uint32_t dummyCycle);
48
49 static uint32_t Cy_SMIF_Reverse4ByteEndian(uint32_t in);
50
51
52 static cy_en_smif_status_t Cy_SMIF_HyperBus_MMIO_Read(SMIF_Type *base,
53 cy_en_smif_slave_select_t slave,
54 cy_en_hb_burst_type_t burstType,
55 uint32_t readAddress,
56 uint32_t sizeInHalfWord,
57 uint16_t buf[],
58 uint32_t dummyCycle,
59 bool doubleLat,
60 bool isblockingMode,
61 cy_stc_smif_context_t *context);
62
63
64
65 /*******************************************************************************
66 * Function Name: Cy_SMIF_Reverse4ByteEndian
67 ****************************************************************************//**
68 *
69 * This function reverses endianness of 32 bit input
70 *
71 * \param in
72 * input 32 bit data to be reversed its endianness
73 *
74 * \return 32 bit data which has been reversed its endianness
75 *
76 *******************************************************************************/
Cy_SMIF_Reverse4ByteEndian(uint32_t in)77 static uint32_t Cy_SMIF_Reverse4ByteEndian(uint32_t in)
78 {
79 return ((in & 0xFF000000UL) >> 24UL) |
80 ((in & 0x00FF0000UL) >> 8UL) |
81 ((in & 0x0000FF00UL) << 8UL) |
82 ((in & 0x000000FFUL) << 24UL);
83 }
84
85 /*******************************************************************************
86 * Function Name: Cy_SMIF_HyperBus_InitDevice
87 ****************************************************************************//**
88 *
89 * This function sets up SMIF registers which is used in XIP mode for hyper bus
90 * memory.
91 *
92 * base: Holds the base address of the SMIF base registers.
93 *
94 * memCfg: Configuration to be applied to the SMIF device \ref cy_stc_smif_mem_config_t
95 *
96 *******************************************************************************/
Cy_SMIF_HyperBus_InitDevice(SMIF_Type * base,const cy_stc_smif_mem_config_t * memCfg,cy_stc_smif_context_t * context)97 cy_en_smif_status_t Cy_SMIF_HyperBus_InitDevice(SMIF_Type *base, const cy_stc_smif_mem_config_t *memCfg, cy_stc_smif_context_t *context)
98 {
99 cy_stc_smif_hbmem_device_config_t *config = memCfg->hbdeviceCfg;
100 SMIF_DEVICE_Type volatile * dev = Cy_SMIF_GetDeviceBySlot(base, memCfg->slaveSelect);
101
102 #if (CY_IP_MXSMIF_VERSION>=4)
103 /* DDR_PIPELINE_POS_DAT should be SET for RX Capture mode xSPI */
104 if (_FLD2VAL(SMIF_CORE_CTL2_RX_CAPTURE_MODE, (SMIF_CTL2(base))) == (uint32_t)CY_SMIF_SEL_XSPI_HYPERBUS_WITH_DQS)
105 {
106 SMIF_DEVICE_RX_CAPTURE_CONFIG(dev) |= _VAL2FLD(SMIF_CORE_DEVICE_RX_CAPTURE_CONFIG_DDR_PIPELINE_POS_DAT, 1U);
107 }
108 #endif
109 /* Check if SMIF XIP is enabled */
110 if ((_FLD2VAL(SMIF_CTL_XIP_MODE, SMIF_CTL(base)) != 1U) && (0U != (context->flags & CY_SMIF_FLAG_MEMORY_MAPPED)))
111 {
112
113 /****************************/
114 /* Set XIP Read Sequence */
115 /****************************/
116
117 SMIF_DEVICE_RD_CMD_CTL(dev) = (_VAL2FLD(SMIF_DEVICE_RD_CMD_CTL_CODE, (uint32_t)config->xipReadCmd) |
118 _VAL2FLD(SMIF_DEVICE_RD_CMD_CTL_DDR_MODE, CY_SMIF_DDR) |
119 _VAL2FLD(SMIF_DEVICE_RD_CMD_CTL_WIDTH, CY_SMIF_WIDTH_OCTAL) |
120 _VAL2FLD(SMIF_DEVICE_RD_CMD_CTL_PRESENT2, CY_SMIF_PRESENT_1BYTE));
121
122 SMIF_DEVICE_RD_ADDR_CTL(dev) = (_VAL2FLD(SMIF_DEVICE_RD_ADDR_CTL_WIDTH, CY_SMIF_WIDTH_OCTAL) |
123 _VAL2FLD(SMIF_DEVICE_RD_ADDR_CTL_DDR_MODE, CY_SMIF_DDR));
124
125 SMIF_DEVICE_RD_MODE_CTL(dev) = (_VAL2FLD(SMIF_DEVICE_RD_MODE_CTL_CODE, 0UL) |
126 _VAL2FLD(SMIF_DEVICE_RD_MODE_CTL_WIDTH, CY_SMIF_WIDTH_SINGLE) |
127 _VAL2FLD(SMIF_DEVICE_RD_MODE_CTL_DDR_MODE, CY_SMIF_SDR) |
128 _VAL2FLD(SMIF_DEVICE_RD_MODE_CTL_PRESENT2, CY_SMIF_NOT_PRESENT));
129
130 SMIF_DEVICE_RD_DATA_CTL(dev) = (_VAL2FLD(SMIF_DEVICE_RD_DATA_CTL_WIDTH, CY_SMIF_WIDTH_OCTAL) |
131 _VAL2FLD(SMIF_DEVICE_RD_DATA_CTL_DDR_MODE, CY_SMIF_DDR));
132
133
134
135 /*****************************/
136 /* Set XIP Write Sequence */
137 /*****************************/
138 SMIF_DEVICE_WR_CMD_CTL(dev) = ( _VAL2FLD(SMIF_DEVICE_WR_CMD_CTL_CODE, config->xipWriteCmd) |
139 _VAL2FLD(SMIF_DEVICE_WR_CMD_CTL_DDR_MODE, CY_SMIF_DDR) |
140 _VAL2FLD(SMIF_DEVICE_WR_CMD_CTL_WIDTH, CY_SMIF_WIDTH_OCTAL) |
141 _VAL2FLD(SMIF_DEVICE_WR_CMD_CTL_PRESENT2, CY_SMIF_PRESENT_1BYTE));
142
143 SMIF_DEVICE_WR_ADDR_CTL(dev) = (_VAL2FLD(SMIF_DEVICE_WR_ADDR_CTL_WIDTH, CY_SMIF_WIDTH_OCTAL) |
144 _VAL2FLD(SMIF_DEVICE_WR_ADDR_CTL_DDR_MODE, CY_SMIF_DDR));
145
146 SMIF_DEVICE_WR_MODE_CTL(dev) = (_VAL2FLD(SMIF_DEVICE_WR_MODE_CTL_CODE, 0UL) |
147 _VAL2FLD(SMIF_DEVICE_WR_MODE_CTL_WIDTH, CY_SMIF_WIDTH_SINGLE) |
148 _VAL2FLD(SMIF_DEVICE_WR_MODE_CTL_DDR_MODE, CY_SMIF_SDR) |
149 _VAL2FLD(SMIF_DEVICE_WR_MODE_CTL_PRESENT2,CY_SMIF_NOT_PRESENT));
150
151 SMIF_DEVICE_WR_DATA_CTL(dev) = (_VAL2FLD(SMIF_DEVICE_WR_DATA_CTL_WIDTH, CY_SMIF_WIDTH_OCTAL) |
152 _VAL2FLD(SMIF_DEVICE_WR_DATA_CTL_DDR_MODE, CY_SMIF_DDR));
153
154 SMIF_DEVICE_ADDR(dev) = (SMIF_DEVICE_ADDR_ADDR_Msk & memCfg->baseAddress);
155
156 /* Convert the size in the mask */
157 SMIF_DEVICE_MASK(dev)= SMIF_DEVICE_MASK_MASK_Msk & (~((uint32_t)(config->memSize)) + 1UL);
158
159 SMIF_DEVICE_ADDR_CTL(dev) = (_VAL2FLD(SMIF_DEVICE_ADDR_CTL_SIZE3, CY_SMIF_XIP_ADDRESS_5_BYTE) |
160 _VAL2FLD(SMIF_DEVICE_ADDR_CTL_DIV2, 0U));
161 }
162
163 #if (CY_IP_MXSMIF_VERSION>=4)
164 if (_FLD2VAL(SMIF_CORE_CTL2_RX_CAPTURE_MODE, (SMIF_CTL2(base))) == (uint32_t)CY_SMIF_SEL_XSPI_HYPERBUS_WITH_DQS)
165 {
166 Cy_SMIF_HB_SetDummyCycles(dev, config->hbDevType, config->dummyCycles - 1U);
167 }
168 else
169 {
170 Cy_SMIF_HB_SetDummyCycles(dev, config->hbDevType, config->dummyCycles);
171 }
172 #else
173 /* Note: All read/write sequence settings depending on the dummy cycles are moved to the following function */
174 /* because it may be necessary to update them during runtime when the latency settings in the connected */
175 /* memories have been changed. Cy_SMIF_HB_SetDummyCycles can then be used for that purpose. */
176 Cy_SMIF_HB_SetDummyCycles(dev, config->hbDevType, config->dummyCycles -1U);
177 #endif
178 context->dummyCycles = config->dummyCycles;
179
180 context->preXIPDataRate = CY_SMIF_DDR;
181
182 /* The device control register initialization */
183 SMIF_DEVICE_CTL(dev) = _VAL2FLD(SMIF_DEVICE_CTL_WR_EN, 1U) |
184 _VAL2FLD(SMIF_DEVICE_CTL_CRYPTO_EN, 0U) |
185 _VAL2FLD(SMIF_DEVICE_CTL_DATA_SEL, CY_SMIF_DATA_SEL0) |
186 _VAL2FLD(SMIF_DEVICE_CTL_MERGE_EN, ((bool)(memCfg->flags & CY_SMIF_FLAG_MERGE_ENABLE))? 1U : 0U) |
187 _VAL2FLD(SMIF_DEVICE_CTL_MERGE_TIMEOUT, (uint32_t)memCfg->mergeTimeout) |
188 SMIF_DEVICE_CTL_ENABLED_Msk;
189
190 return CY_SMIF_SUCCESS;
191 }
192
193 /*******************************************************************************
194 * Function Name: Cy_SMIF_HB_SetDummyCycles
195 ****************************************************************************//**
196 *
197 * This function updates the dummy cycles in the XIP read/write sequences
198 * based on the specified latency code and device type.
199 * If called for an already initialized device during runtime (e.g. after
200 * updating the latency settings in the connected memory) ensure that SMIF is
201 * not busy and no access to XIP address space happens!
202 *
203 * dev
204 * Holds the base address of the SMIF Device registers.
205 *
206 * hbDevType
207 * Device type (HyperFlash or HyperRAM)
208 *
209 * dummyCycle
210 * The amount of dummy cycles to use
211 *
212 * return
213 * - \ref CY_SMIF_SUCCESS
214 *
215 *******************************************************************************/
Cy_SMIF_HB_SetDummyCycles(volatile SMIF_DEVICE_Type * dev,cy_en_smif_hb_dev_type_t hbDevType,uint32_t dummyCycle)216 static void Cy_SMIF_HB_SetDummyCycles(volatile SMIF_DEVICE_Type *dev, cy_en_smif_hb_dev_type_t hbDevType, uint32_t dummyCycle)
217 {
218 /**********************************************/
219 /* Set dummy cycles for XIP Read Sequence */
220 /**********************************************/
221
222 /*** Set dummy ***/
223 {
224 /* For Hyperbus, (RD DUMMY_CTL SIZE5 + 2) = initial latency */
225 SMIF_DEVICE_RD_DUMMY_CTL(dev) = (_VAL2FLD(SMIF_DEVICE_RD_DUMMY_CTL_SIZE5, (dummyCycle - 1UL)) |
226 _VAL2FLD(SMIF_DEVICE_RD_DUMMY_CTL_PRESENT2, 1U));
227
228 }
229
230 /*** Set bound ***/
231 {
232 SMIF_DEVICE_RD_BOUND_CTL(dev) = (_VAL2FLD(SMIF_DEVICE_RD_BOUND_CTL_SIZE5, dummyCycle) |
233 _VAL2FLD(SMIF_DEVICE_RD_BOUND_CTL_SUB_PAGE_SIZE,SUB_PAGE_SIZE_16BYTE) |
234 _VAL2FLD(SMIF_DEVICE_RD_BOUND_CTL_SUB_PAGE_NR,SUB_PAGE_2_PER_PAGE) |
235 _VAL2FLD(SMIF_DEVICE_RD_BOUND_CTL_SUBSEQ_BOUND_EN,0UL) |
236 _VAL2FLD(SMIF_DEVICE_RD_BOUND_CTL_PRESENT, 1UL));
237 }
238
239 /**********************************************/
240 /* Set dummy cycles for XIP Write Sequence */
241 /**********************************************/
242 /*** Set dummy ***/
243 {
244 if(hbDevType == CY_SMIF_HB_FLASH)
245 {
246 SMIF_DEVICE_WR_DUMMY_CTL(dev) = (_VAL2FLD(SMIF_DEVICE_WR_DUMMY_CTL_SIZE5, 0UL) |
247 _VAL2FLD(SMIF_DEVICE_WR_DUMMY_CTL_PRESENT2, CY_SMIF_NOT_PRESENT) |
248 _VAL2FLD(SMIF_DEVICE_WR_DUMMY_CTL_RWDS_EN, 0UL));
249 }
250 else
251 {
252 // For Hyperbus, (RD DUMMY_CTL SIZE5 + 2) = initial latency
253 SMIF_DEVICE_WR_DUMMY_CTL(dev) = (_VAL2FLD(SMIF_DEVICE_WR_DUMMY_CTL_SIZE5, (dummyCycle - 1U)) |
254 _VAL2FLD(SMIF_DEVICE_WR_DUMMY_CTL_PRESENT2, 1U) |
255 _VAL2FLD(SMIF_DEVICE_WR_DUMMY_CTL_RWDS_EN, 1UL));
256 }
257 }
258 return;
259 }
260
261 /*******************************************************************************
262 * Function Name: Cy_SMIF_HyperBus_CalibrateDelay
263 ****************************************************************************//**
264 *
265 * This function reads the calibration data pattern in the Hyper memory for every
266 * delay tap of the currently selected delay line and records whether it matches
267 * the reference pattern. After all taps have been scanned, it determines the
268 * center tap of the longest sequence of matches and applies this tap.
269 *
270 * \note Function assumes that any SMIF has the same number of delay taps
271 *
272 *
273 *******************************************************************************/
Cy_SMIF_HyperBus_CalibrateDelay(SMIF_Type * base,cy_stc_smif_mem_config_t * memConfig,uint8_t dummyCycles,uint32_t calibrationDataOffsetAddress,cy_stc_smif_context_t * context)274 cy_en_smif_status_t Cy_SMIF_HyperBus_CalibrateDelay(SMIF_Type *base, cy_stc_smif_mem_config_t *memConfig, uint8_t dummyCycles, uint32_t calibrationDataOffsetAddress, cy_stc_smif_context_t *context)
275 {
276 uint16_t tapNum;
277 cy_en_smif_status_t SMIF_Status = CY_SMIF_SUCCESS;
278 uint16_t dataRead[CY_SMIF_HB_CALIBRATION_DATA_PATTERN_LENGTH];
279 uint16_t delayTapNum = SMIF_DELAY_TAPS_NR;
280 CY_ASSERT(delayTapNum < 256U); // Assume "delayTapNum" is less than 256
281 static bool isMatch[256U]; // static variable to avoid consuming stack.
282
283 //SMIF_DEVICE_Type volatile * device = Cy_SMIF_GetDeviceBySlot(base, slaveId);
284 cy_en_smif_mode_t smifModeBackup = Cy_SMIF_GetMode(base);
285
286 // Reading of calibration data pattern needs to happen in SMIF MMIO mode so that it can be ensured that
287 // there will be burst access happening and there are no pauses in between reading of individual words of the pattern
288 Cy_SMIF_SetMode(base, CY_SMIF_NORMAL);
289
290 SMIF_Status = Cy_SMIF_HyperBus_EraseSector(base,memConfig,calibrationDataOffsetAddress,context);
291 CY_MISRA_DEVIATE_BLOCK_START('MISRA C-2012 Rule 11.3', 3, \
292 'Checked manually. Intentional expression The object pointer of type non "uint8_t (*)[12]" is cast to type "uint16_t *".')
293 if(SMIF_Status == CY_SMIF_SUCCESS)
294 {
295 SMIF_Status = Cy_SMIF_HyperBus_Write(base,
296 memConfig,
297 CY_SMIF_HB_COUTINUOUS_BURST,
298 calibrationDataOffsetAddress, // address
299 CY_SMIF_HB_CALIBRATION_DATA_PATTERN_LENGTH / 2U, // size in half word
300 (uint16_t*)&Cy_SMIF_HB_CalibrationDataPattern,
301 CY_SMIF_HB_FLASH,
302 dummyCycles,
303 true, // Blocking mode
304 context
305 );
306 }
307 else
308 {
309 return SMIF_Status;
310 }
311 CY_MISRA_BLOCK_END('MISRA C-2012 Rule 11.3')
312 for(tapNum = 0U; tapNum < (uint16_t)delayTapNum; tapNum++)
313 {
314 uint16_t timeout = DEVICEREADY_CHECK_TIMEOUT;
315 while(Cy_SMIF_BusyCheck(base) && (timeout > 0UL))
316 {
317 timeout--;
318 Cy_SysLib_Delay(100U);
319 /* Wait for the device to be ready */
320 }
321 if(timeout == 0U)
322 {
323 return CY_SMIF_EXCEED_TIMEOUT;
324 }
325 #if (CY_IP_MXSMIF_VERSION==2)
326 (void)Cy_SMIF_Set_DelayTapSel(base, (uint8_t)tapNum);
327 #endif /*(CY_IP_MXSMIF_VERSION==2)*/
328 (void)memset(dataRead, 0,CY_SMIF_HB_CALIBRATION_DATA_PATTERN_LENGTH * 2U);
329 SMIF_Status = Cy_SMIF_HyperBus_Read(base,
330 memConfig,
331 CY_SMIF_HB_COUTINUOUS_BURST,
332 calibrationDataOffsetAddress, // address
333 CY_SMIF_HB_CALIBRATION_DATA_PATTERN_LENGTH / 2U, // size in half word
334 (uint16_t*)dataRead,
335 dummyCycles,
336 false, // single initial latency
337 true, // blocking mode
338 context
339 );
340 if(SMIF_Status == CY_SMIF_SUCCESS)
341 {
342 // Record whether the current tap read data matches the reference data
343 isMatch[tapNum] = (memcmp((uint8_t*)&dataRead, Cy_SMIF_HB_CalibrationDataPattern, CY_SMIF_HB_CALIBRATION_DATA_PATTERN_LENGTH) == 0) ? true : false;
344 }
345 }
346
347 uint16_t bestTapNum = 0xffffu;
348 uint16_t consecutiveMatchNum = 0u;
349 uint16_t maxConsecutiveMatchNum = 0u;
350
351 // Determine the longest consecutive match
352 for(tapNum = 0u; tapNum < delayTapNum; tapNum++)
353 {
354 if(isMatch[tapNum] == true)
355 {
356 consecutiveMatchNum += 1u;
357 }
358 else
359 {
360 if(maxConsecutiveMatchNum < consecutiveMatchNum)
361 {
362 // Sequence of matches ended and it is a new longest sequence -> update the best tap number and prepare vars for next run
363 maxConsecutiveMatchNum = consecutiveMatchNum;
364 bestTapNum = tapNum - ((maxConsecutiveMatchNum + 1u) / 2u);
365 consecutiveMatchNum = 0u;
366 }
367 }
368 }
369
370 // Special case: All taps had a match -> use the center tap of the total taps number
371 if(maxConsecutiveMatchNum < consecutiveMatchNum)
372 {
373 bestTapNum = (uint16_t)(delayTapNum - ((consecutiveMatchNum + 1u) / 2u));
374 }
375 #if (CY_IP_MXSMIF_VERSION==2)
376 // If a match has been found, apply the best tap
377 if(bestTapNum != 0xffffu)
378 {
379 (void)Cy_SMIF_Set_DelayTapSel(base,(uint8_t)bestTapNum);
380 }
381 else
382 {
383 // No match has been found
384 SMIF_Status = CY_SMIF_GENERAL_ERROR;
385 }
386 #endif /*(CY_IP_MXSMIF_VERSION==2)*/
387 Cy_SMIF_SetMode(base, smifModeBackup);
388 (void)bestTapNum;
389 return SMIF_Status;
390 }
391
392
393 /*******************************************************************************
394 * Function Cy_SMIF_HyperBus_Read
395 ****************************************************************************//**
396 *
397 * This function reads data from hyper bus memory in MMIO mode.
398 *
399 * \param base
400 * Holds the base address of the SMIF block registers.
401 *
402 * \param memConfig
403 * SMIF memory configuration structure for memory mode of operation.
404 *
405 * \param burstType
406 * Specifies wrapped or continuous burst. \ref en_hb_bust_type_t
407 *
408 * \param readAddress
409 * Specifies address of external device to be read.
410 *
411 * \param sizeInHalfWord
412 * Specifies memory size to be read.
413 * Note hyper bus memory have 16bit data per each address.
414 *
415 * \param buf
416 * Pointer to buffer where read data to be stored
417 *
418 * \param dummyCycles
419 * Number of dummy cycles required before actual read data.
420 *
421 * \param doubleLat
422 * double initial latency or single initial latency
423 *
424 * \param isblockingMode
425 * Blocking mode or not. if this is true, process waits for the read finished in this
426 * function. unless, the process does not wait and exit function.
427 *
428 * \param context
429 * Passes a configuration structure that contains the transfer parameters of the
430 * SMIF block.
431 *
432 * \return \ref cy_en_smif_status_t
433 *
434 *******************************************************************************/
Cy_SMIF_HyperBus_Read(SMIF_Type * base,cy_stc_smif_mem_config_t * memConfig,cy_en_hb_burst_type_t burstType,uint32_t readAddress,uint32_t sizeInHalfWord,uint16_t buf[],uint32_t dummyCycles,bool doubleLat,bool isblockingMode,cy_stc_smif_context_t * context)435 cy_en_smif_status_t Cy_SMIF_HyperBus_Read(SMIF_Type *base,
436 cy_stc_smif_mem_config_t *memConfig,
437 cy_en_hb_burst_type_t burstType,
438 uint32_t readAddress,
439 uint32_t sizeInHalfWord,
440 uint16_t buf[],
441 uint32_t dummyCycles,
442 bool doubleLat,
443 bool isblockingMode,
444 cy_stc_smif_context_t *context)
445 {
446 cy_en_smif_status_t status;
447 status = Cy_SMIF_HyperBus_MMIO_Read(base,
448 memConfig->slaveSelect,
449 burstType,
450 readAddress,
451 sizeInHalfWord,
452 buf,
453 dummyCycles,
454 doubleLat,
455 isblockingMode,
456 context
457 );
458 return status;
459 }
460
461 /*******************************************************************************
462 * Function Cy_SMIF_HyperBus_Write
463 ****************************************************************************//**
464 *
465 * This function writes data into hyper bus memory in MMIO mode.
466 *
467 * \param base
468 * Holds the base address of the SMIF block registers.
469 *
470 * \param memconfig
471 * * SMIF memory configuration structure for memory mode of operation.
472 *
473 * \param burstType
474 * Specifies wrapped or continuous burst. \ref en_hb_bust_type_t
475 *
476 * \param writeAddress
477 * Specifies address of external device to be write.
478 *
479 * \param sizeInHalfWord
480 * Specifies memory size to be read.
481 * Note hyper bus memory have 16bit data per each address.
482 *
483 * \param buf
484 * Pointer to buffer where read data to be stored
485 *
486 * \param hbDevType
487 * Specifies hyper bus type. FLASH or SRAM. \ref cy_en_smif_hb_dev_type_t
488 *
489 * \param dummyCycles
490 * Number of dummyCycles to be inserted before write operation.
491 *
492 * \param isblockingMode
493 * Blocking mode or not. if this is true, process waits for the read finished in this
494 * function. unless, the process does not wait and exit function.
495 *
496 * \param context
497 * Passes a configuration structure that contains the transfer parameters of the
498 * SMIF block.
499 *
500 * \return \ref cy_en_smif_status_t
501 *
502 *******************************************************************************/
Cy_SMIF_HyperBus_Write(SMIF_Type * base,cy_stc_smif_mem_config_t * memConfig,cy_en_hb_burst_type_t burstType,uint32_t writeAddress,uint32_t sizeInHalfWord,uint16_t buf[],cy_en_smif_hb_dev_type_t hbDevType,uint32_t dummyCycles,bool isblockingMode,cy_stc_smif_context_t * context)503 cy_en_smif_status_t Cy_SMIF_HyperBus_Write(SMIF_Type *base,
504 cy_stc_smif_mem_config_t *memConfig,
505 cy_en_hb_burst_type_t burstType,
506 uint32_t writeAddress,
507 uint32_t sizeInHalfWord,
508 uint16_t buf[],
509 cy_en_smif_hb_dev_type_t hbDevType,
510 uint32_t dummyCycles,
511 bool isblockingMode,
512 cy_stc_smif_context_t *context)
513 {
514 cy_en_smif_status_t status = CY_SMIF_GENERAL_ERROR;
515 uint32_t i_WriteAddr = 0U;
516 uint32_t sizetowrite = 8U; // recommended to write 16 bytes at a time. since size is in half word(2 bytes) it is 8.
517 if(sizeInHalfWord > 0U && sizeInHalfWord < sizetowrite)
518 {
519 sizetowrite = sizeInHalfWord;
520 }
521 int sizeInInt = (int) sizeInHalfWord;
522
523 while( sizeInInt > 0)
524 {
525
526 if(hbDevType == CY_SMIF_HB_FLASH)
527 {
528 writeBuf = (uint16_t)CY_SMIF_NOR_UNLOCK_DATA1;
529 status = Cy_SMIF_HyperBus_MMIO_Write(base,
530 memConfig->slaveSelect,
531 burstType,
532 (uint32_t)CY_SMIF_HB_FLASH_UNLOCK_ADDR1,
533 HB_REG_SIZE_IN_HALFWORD,
534 &writeBuf,
535 hbDevType,
536 dummyCycles,
537 isblockingMode,
538 context
539 );
540
541 writeBuf = (uint16_t)CY_SMIF_NOR_UNLOCK_DATA2;
542 status = Cy_SMIF_HyperBus_MMIO_Write(base,
543 memConfig->slaveSelect,
544 burstType,
545 (uint32_t)CY_SMIF_HB_FLASH_UNLOCK_ADDR2,
546 HB_REG_SIZE_IN_HALFWORD,
547 &writeBuf,
548 hbDevType,
549 dummyCycles,
550 isblockingMode,
551 context
552 );
553
554 writeBuf = (uint16_t)CY_SMIF_NOR_UNLOCK_BYPASS_PROGRAM_CMD;
555 status = Cy_SMIF_HyperBus_MMIO_Write(base,
556 memConfig->slaveSelect,
557 burstType,
558 (uint32_t)CY_SMIF_HB_FLASH_UNLOCK_ADDR1,
559 HB_REG_SIZE_IN_HALFWORD,
560 &writeBuf,
561 hbDevType,
562 dummyCycles,
563 isblockingMode,
564 context
565 );
566 if (status != CY_SMIF_SUCCESS)
567 {
568 return status;
569 }
570 }
571 status = Cy_SMIF_HyperBus_MMIO_Write(base,
572 memConfig->slaveSelect,
573 burstType,
574 i_WriteAddr + writeAddress,
575 sizetowrite,
576 (uint16_t*)&buf[i_WriteAddr],
577 hbDevType,
578 dummyCycles,
579 isblockingMode,
580 context
581 );
582
583 if(hbDevType == CY_SMIF_HB_FLASH)
584 {
585 uint16_t readStatus = 0x0000U;
586 uint16_t timeout = DEVICEREADY_CHECK_TIMEOUT;
587 do
588 {
589 status = CY_SMIF_HyperBus_ReadStatus(base, memConfig, &readStatus,context );
590 timeout --;
591 Cy_SysLib_Delay(100U);
592 } while(((readStatus & (uint16_t)CY_SMIF_DEV_RDY_MASK) == 0U) && (timeout > 0U)); // wait for the device becoming ready
593 if(timeout == 0U)
594 {
595 return CY_SMIF_EXCEED_TIMEOUT;
596 }
597 }
598 sizeInInt -= (int)sizetowrite;
599 i_WriteAddr += sizetowrite;
600
601 if(sizeInInt > 0 && sizeInInt < (int)sizetowrite)
602 {
603 sizetowrite = (uint32_t)sizeInInt;
604 }
605 }
606 return status;
607 }
608
609 /*******************************************************************************
610 * Function Name: CY_SMIF_HyperBus_ReadStatus
611 ****************************************************************************//**
612 *
613 * This function reads the flash status register bits.
614 *
615 * \param base
616 * Holds the base address of the SMIF block registers.
617 *
618 * \param memConfig
619 * SMIF memory configuration structure for memory mode of operation.
620 *
621 * \param regStatus
622 * output status register value.
623 *
624 *******************************************************************************/
CY_SMIF_HyperBus_ReadStatus(SMIF_Type * base,cy_stc_smif_mem_config_t * memConfig,uint16_t * regStatus,cy_stc_smif_context_t * context)625 cy_en_smif_status_t CY_SMIF_HyperBus_ReadStatus(SMIF_Type *base, cy_stc_smif_mem_config_t *memConfig, uint16_t *regStatus, cy_stc_smif_context_t *context)
626 {
627 cy_en_smif_status_t status;
628 writeBuf = (uint16_t)CY_SMIF_NOR_STATUS_REG_READ_CMD;
629 uint16_t readstatus = 0x0000U;
630 status = Cy_SMIF_HyperBus_MMIO_Write(base,
631 memConfig->slaveSelect,
632 CY_SMIF_HB_WRAPPED_BURST,
633 (uint32_t)CY_SMIF_HB_FLASH_UNLOCK_ADDR1,
634 HB_REG_SIZE_IN_HALFWORD,
635 &writeBuf,
636 CY_SMIF_HB_FLASH,
637 context->dummyCycles,
638 true,
639 context
640 );
641 status = Cy_SMIF_HyperBus_MMIO_Read(base,
642 memConfig->slaveSelect,
643 CY_SMIF_HB_COUTINUOUS_BURST,
644 0x0000U,
645 HB_REG_SIZE_IN_HALFWORD,
646 &readstatus,
647 context->dummyCycles,
648 false,
649 true,
650 context
651 );
652 *regStatus = readstatus;
653 return status;
654 }
655
656 /*******************************************************************************
657 * Function Name: CY_SMIF_HyperBus_ClearStatus
658 ****************************************************************************//**
659 *
660 * This function clears the flash status register bits.
661 *
662 * \param base
663 * Holds the base address of the SMIF block registers.
664 *
665 * \param memConfig
666 * SMIF memory configuration structure for memory mode of operation.
667 *
668 *******************************************************************************/
CY_SMIF_HyperBus_ClearStatus(SMIF_Type * base,cy_stc_smif_mem_config_t * memConfig,cy_stc_smif_context_t * context)669 cy_en_smif_status_t CY_SMIF_HyperBus_ClearStatus(SMIF_Type *base, cy_stc_smif_mem_config_t *memConfig, cy_stc_smif_context_t *context)
670 {
671 cy_en_smif_status_t status;
672 writeBuf = (uint16_t)CY_SMIF_NOR_STATUS_REG_CLEAR_CMD;
673
674 status = Cy_SMIF_HyperBus_MMIO_Write(base,
675 memConfig->slaveSelect,
676 CY_SMIF_HB_WRAPPED_BURST,
677 (uint32_t)CY_SMIF_HB_FLASH_UNLOCK_ADDR1,
678 HB_REG_SIZE_IN_HALFWORD,
679 &writeBuf,
680 CY_SMIF_HB_FLASH,
681 context->dummyCycles,
682 true,
683 context
684 );
685 return status;
686 }
687 /*******************************************************************************
688 * Function Name: Cy_SMIF_HyperBus_EraseSector
689 ****************************************************************************//**
690 *
691 * This function Erases the data in the given sector.
692 *
693 * \param base
694 * Holds the base address of the SMIF block registers.
695 *
696 * \param memConfig
697 * SMIF memory configuration structure for memory mode of operation.
698 *
699 * \param offset
700 * offset of the sector to be erased.
701 *
702 *******************************************************************************/
Cy_SMIF_HyperBus_EraseSector(SMIF_Type * base,cy_stc_smif_mem_config_t * memConfig,uint32_t offset,cy_stc_smif_context_t * context)703 cy_en_smif_status_t Cy_SMIF_HyperBus_EraseSector(SMIF_Type *base, cy_stc_smif_mem_config_t *memConfig, uint32_t offset, cy_stc_smif_context_t *context)
704 {
705 cy_en_smif_status_t status;
706
707 writeBuf = (uint16_t)CY_SMIF_NOR_UNLOCK_DATA1;
708 status = Cy_SMIF_HyperBus_MMIO_Write(base,
709 memConfig->slaveSelect,
710 CY_SMIF_HB_WRAPPED_BURST,
711 (uint32_t)CY_SMIF_HB_FLASH_UNLOCK_ADDR1,
712 HB_REG_SIZE_IN_HALFWORD,
713 &writeBuf,
714 CY_SMIF_HB_FLASH,
715 context->dummyCycles,
716 true,
717 context
718 );
719
720 writeBuf = (uint16_t)CY_SMIF_NOR_UNLOCK_DATA2;
721 status = Cy_SMIF_HyperBus_MMIO_Write(base,
722 memConfig->slaveSelect,
723 CY_SMIF_HB_WRAPPED_BURST,
724 (uint32_t)CY_SMIF_HB_FLASH_UNLOCK_ADDR2,
725 HB_REG_SIZE_IN_HALFWORD,
726 &writeBuf,
727 CY_SMIF_HB_FLASH,
728 context->dummyCycles,
729 true,
730 context
731 );
732
733 writeBuf = (uint16_t)CY_SMIF_NOR_ERASE_SETUP_CMD;
734 status = Cy_SMIF_HyperBus_MMIO_Write(base,
735 memConfig->slaveSelect,
736 CY_SMIF_HB_WRAPPED_BURST,
737 (uint32_t)CY_SMIF_HB_FLASH_UNLOCK_ADDR1,
738 HB_REG_SIZE_IN_HALFWORD,
739 &writeBuf,
740 CY_SMIF_HB_FLASH,
741 context->dummyCycles,
742 true,
743 context
744 );
745
746 writeBuf = (uint16_t)CY_SMIF_NOR_UNLOCK_DATA1;
747 status = Cy_SMIF_HyperBus_MMIO_Write(base,
748 memConfig->slaveSelect,
749 CY_SMIF_HB_WRAPPED_BURST,
750 (uint32_t)CY_SMIF_HB_FLASH_UNLOCK_ADDR1,
751 HB_REG_SIZE_IN_HALFWORD,
752 &writeBuf,
753 CY_SMIF_HB_FLASH,
754 context->dummyCycles,
755 true,
756 context
757 );
758
759 writeBuf = (uint16_t)CY_SMIF_NOR_UNLOCK_DATA2;
760 status = Cy_SMIF_HyperBus_MMIO_Write(base,
761 memConfig->slaveSelect,
762 CY_SMIF_HB_WRAPPED_BURST,
763 (uint32_t)CY_SMIF_HB_FLASH_UNLOCK_ADDR2,
764 HB_REG_SIZE_IN_HALFWORD,
765 &writeBuf,
766 CY_SMIF_HB_FLASH,
767 context->dummyCycles,
768 true,
769 context
770 );
771
772 writeBuf = (uint16_t)CY_SMIF_NOR_SECTOR_ERASE_CMD;
773
774 status = Cy_SMIF_HyperBus_MMIO_Write(base,
775 memConfig->slaveSelect,
776 CY_SMIF_HB_WRAPPED_BURST,
777 offset,
778 HB_REG_SIZE_IN_HALFWORD,
779 &writeBuf,
780 CY_SMIF_HB_FLASH,
781 context->dummyCycles,
782 true,
783 context
784 );
785
786 uint16_t readStatus = 0x0000U;
787 uint16_t timeout = DEVICEREADY_CHECK_TIMEOUT;
788 do
789 {
790 status = CY_SMIF_HyperBus_ReadStatus(base, memConfig, &readStatus,context );
791 timeout --;
792 Cy_SysLib_Delay(100U);
793 } while(((readStatus & (uint16_t)CY_SMIF_DEV_RDY_MASK) == 0U) && (timeout > 0U)); // wait for the device becoming ready
794 if(timeout == 0U)
795 {
796 status = CY_SMIF_EXCEED_TIMEOUT;
797 }
798 return status;
799 }
800
801 /*******************************************************************************
802 * Function Name: Cy_SMIF_HyperBus_EraseChip
803 ****************************************************************************//**
804 *
805 * This function Erases the data in the entire flash memory.
806 *
807 * \param base
808 * Holds the base address of the SMIF block registers.
809 *
810 * \param memConfig
811 * SMIF memory configuration structure for memory mode of operation.
812 *
813 *******************************************************************************/
Cy_SMIF_HyperBus_EraseChip(SMIF_Type * base,cy_stc_smif_mem_config_t * memConfig,cy_stc_smif_context_t * context)814 cy_en_smif_status_t Cy_SMIF_HyperBus_EraseChip(SMIF_Type *base, cy_stc_smif_mem_config_t *memConfig, cy_stc_smif_context_t *context)
815 {
816 cy_en_smif_status_t status;
817 uint16_t readStatus = 0x0000U;
818 writeBuf = (uint16_t)CY_SMIF_NOR_UNLOCK_DATA1;
819 status = Cy_SMIF_HyperBus_MMIO_Write(base,
820 memConfig->slaveSelect,
821 CY_SMIF_HB_WRAPPED_BURST,
822 (uint32_t)CY_SMIF_HB_FLASH_UNLOCK_ADDR1,
823 HB_REG_SIZE_IN_HALFWORD,
824 &writeBuf,
825 CY_SMIF_HB_FLASH,
826 context->dummyCycles,
827 true,
828 context
829 );
830
831 writeBuf = (uint16_t)CY_SMIF_NOR_UNLOCK_DATA2;
832 status = Cy_SMIF_HyperBus_MMIO_Write(base,
833 memConfig->slaveSelect,
834 CY_SMIF_HB_WRAPPED_BURST,
835 (uint32_t)CY_SMIF_HB_FLASH_UNLOCK_ADDR2,
836 HB_REG_SIZE_IN_HALFWORD,
837 &writeBuf,
838 CY_SMIF_HB_FLASH,
839 context->dummyCycles,
840 true,
841 context
842 );
843
844 writeBuf = (uint16_t)CY_SMIF_NOR_ERASE_SETUP_CMD;
845 status = Cy_SMIF_HyperBus_MMIO_Write(base,
846 memConfig->slaveSelect,
847 CY_SMIF_HB_WRAPPED_BURST,
848 (uint32_t)CY_SMIF_HB_FLASH_UNLOCK_ADDR1,
849 HB_REG_SIZE_IN_HALFWORD,
850 &writeBuf,
851 CY_SMIF_HB_FLASH,
852 context->dummyCycles,
853 true,
854 context
855 );
856
857 writeBuf = (uint16_t)CY_SMIF_NOR_UNLOCK_DATA1;
858 status = Cy_SMIF_HyperBus_MMIO_Write(base,
859 memConfig->slaveSelect,
860 CY_SMIF_HB_WRAPPED_BURST,
861 (uint32_t)CY_SMIF_HB_FLASH_UNLOCK_ADDR1,
862 HB_REG_SIZE_IN_HALFWORD,
863 &writeBuf,
864 CY_SMIF_HB_FLASH,
865 context->dummyCycles,
866 true,
867 context
868 );
869
870 writeBuf = (uint16_t)CY_SMIF_NOR_UNLOCK_DATA2;
871 status = Cy_SMIF_HyperBus_MMIO_Write(base,
872 memConfig->slaveSelect,
873 CY_SMIF_HB_WRAPPED_BURST,
874 (uint32_t)CY_SMIF_HB_FLASH_UNLOCK_ADDR2,
875 HB_REG_SIZE_IN_HALFWORD,
876 &writeBuf,
877 CY_SMIF_HB_FLASH,
878 context->dummyCycles,
879 true,
880 context
881 );
882
883 writeBuf = (uint16_t)CY_SMIF_NOR_CHIP_ERASE_CMD;
884
885 status = Cy_SMIF_HyperBus_MMIO_Write(base,
886 memConfig->slaveSelect,
887 CY_SMIF_HB_WRAPPED_BURST,
888 (uint32_t)CY_SMIF_HB_FLASH_UNLOCK_ADDR1,
889 HB_REG_SIZE_IN_HALFWORD,
890 &writeBuf,
891 CY_SMIF_HB_FLASH,
892 context->dummyCycles,
893 true, // Blocking mode
894 context
895 );
896
897 uint16_t timeout = DEVICEREADY_CHECK_TIMEOUT;
898 do
899 {
900 status = CY_SMIF_HyperBus_ReadStatus(base, memConfig, &readStatus,context );
901 timeout --;
902 Cy_SysLib_Delay(100U);
903 } while(((readStatus & (uint16_t)CY_SMIF_DEV_RDY_MASK) == 0U) && (timeout > 0U)); // wait for the device becoming ready
904 if(timeout == 0U)
905 {
906 status = CY_SMIF_EXCEED_TIMEOUT;
907 }
908 return status;
909 }
910 /* END of MMIO functions */
911
912
913
914 /*******************************************************************************
915 * Function Cy_SMIF_HyperBus_MMIO_Read
916 ****************************************************************************//**
917 *
918 * This function reads data from hyper bus memory in MMIO mode.
919 *
920 * \param base
921 * Holds the base address of the SMIF block registers.
922 *
923 * \param slave
924 * Specifies slave of external device to be read. \ref cy_en_smif_slave_select_t
925 *
926 * \param burstType
927 * Specifies wrapped or continuous burst. \ref en_hb_bust_type_t
928 *
929 * \param readAddress
930 * Specifies address of external device to be read.
931 *
932 * \param sizeInHalfWord
933 * Specifies memory size to be read.
934 * Note hyper bus memory have 16bit data per each address.
935 *
936 * \param buf
937 * Pointer to buffer where read data to be stored
938 *
939 * \param lcCode
940 * Latency code. This value should be set also to the hyper bus device.
941 *
942 * \param dobleLat
943 * double initial latency or single initial latency
944 *
945 * \param isblockingMode
946 * Blocking mode or not. if this is true, process waits for the read finished in this
947 * function. unless, the process does not wait and exit function.
948 *
949 * \param context
950 * Passes a configuration structure that contains the transfer parameters of the
951 * SMIF block.
952 *
953 * \return \ref cy_en_smif_status_t
954 *
955 *******************************************************************************/
Cy_SMIF_HyperBus_MMIO_Read(SMIF_Type * base,cy_en_smif_slave_select_t slave,cy_en_hb_burst_type_t burstType,uint32_t readAddress,uint32_t sizeInHalfWord,uint16_t buf[],uint32_t dummyCycle,bool doubleLat,bool isblockingMode,cy_stc_smif_context_t * context)956 static cy_en_smif_status_t Cy_SMIF_HyperBus_MMIO_Read(SMIF_Type *base,
957 cy_en_smif_slave_select_t slave,
958 cy_en_hb_burst_type_t burstType,
959 uint32_t readAddress,
960 uint32_t sizeInHalfWord,
961 uint16_t buf[],
962 uint32_t dummyCycle,
963 bool doubleLat,
964 bool isblockingMode,
965 cy_stc_smif_context_t *context)
966 {
967 cy_en_smif_status_t status;
968 uint32_t pageAddr = ((uint32_t)(readAddress >> 3u) & 0x00FFFFFFU);
969 uint16_t addr_first_2bytes = (uint16_t)(pageAddr);
970 // This is the last 8 bits of the 24 bit address. this should go in as part of command
971 uint8_t addr_last_byte = (uint8_t)((pageAddr >> 16u));
972
973 uint32_t address = (uint32_t)( _VAL2FLD(SMIF_HYPERBUS_ADR_LOWER_COL_ADDRESS, readAddress) |
974 _VAL2FLD(SMIF_HYPERBUS_ADR_BYTE_ENABLE, 0x0U) |
975 _VAL2FLD(SMIF_HYPERBUS_ADR_ROW_AND_UPPER_COL_ADDRESS, addr_first_2bytes));
976 uint32_t revOfAddr = Cy_SMIF_Reverse4ByteEndian(address);
977
978 uint16_t cmd = (uint16_t)( _VAL2FLD(SMIF_HYPERBUS_CMD_ADDRESS_LAST_BYTE, addr_last_byte) |
979 _VAL2FLD(SMIF_HYPERBUS_CMD_BURST_TYPE, burstType) |
980 _VAL2FLD(SMIF_HYPERBUS_CMD_TARGET_TYPE, CY_SMIF_HB_TARGET_MEMORY) |
981 _VAL2FLD(SMIF_HYPERBUS_CMD_READ_WRITE, CY_SMIF_HB_READ));
982 /****** Command and Address ******/
983 status = Cy_SMIF_TransmitCommand_Ext(base,
984 cmd,
985 true,
986 CY_SMIF_WIDTH_OCTAL,
987 CY_SMIF_DDR,
988 (uint8_t*)&revOfAddr,
989 4u,
990 CY_SMIF_WIDTH_OCTAL,
991 CY_SMIF_DDR,
992 slave,
993 CY_SMIF_TX_NOT_LAST_BYTE,
994 context);
995 if(status != CY_SMIF_SUCCESS)
996 {
997 return status;
998 }
999
1000 dummyCycle = doubleLat ?
1001 dummyCycle * 2u :
1002 dummyCycle;
1003
1004 if(dummyCycle > 0u)
1005 {
1006 status = Cy_SMIF_SendDummyCycles_Ext(base, CY_SMIF_WIDTH_OCTAL, CY_SMIF_DDR, dummyCycle - 1U);
1007
1008 if(status != CY_SMIF_SUCCESS)
1009 {
1010 return status;
1011 }
1012 }
1013
1014 if(isblockingMode == true)
1015 {
1016 status = Cy_SMIF_ReceiveDataBlocking_Ext(base, (uint8_t *)buf, (sizeInHalfWord*2u), CY_SMIF_WIDTH_OCTAL, CY_SMIF_DDR, context);
1017 }
1018 else
1019 {
1020 status = Cy_SMIF_ReceiveData_Ext(base, (uint8_t *)buf, (sizeInHalfWord*2u), CY_SMIF_WIDTH_OCTAL, CY_SMIF_DDR, NULL, context);
1021 }
1022
1023 return status;
1024 }
1025
1026 /*******************************************************************************
1027 * Function Cy_SMIF_HyperBus_MMIO_Write
1028 ****************************************************************************//**
1029 *
1030 * This function writes data into hyper bus memory in MMIO mode.
1031 *
1032 * \param base
1033 * Holds the base address of the SMIF block registers.
1034 *
1035 * \param slave
1036 * Specifies slave of external device to be read. \ref cy_en_smif_slave_select_t
1037 *
1038 * \param burstType
1039 * Specifies wrapped or continuous burst. \ref en_hb_bust_type_t
1040 *
1041 * \param readAddress
1042 * Specifies address of external device to be read.
1043 *
1044 * \param sizeInHalfWord
1045 * Specifies memory size to be read.
1046 * Note hyper bus memory have 16bit data per each address.
1047 *
1048 * \param buf
1049 * Pointer to buffer where read data to be stored
1050 *
1051 * \param hbDevType
1052 * Specifies hyper bus type. FLASH or SRAM. \ref cy_en_smif_hb_dev_type_t
1053 *
1054 * \param lcCode
1055 * Latency code. This value should be set also to the hyper bus device.
1056 *
1057 * \param isblockingMode
1058 * Blocking mode or not. if this is true, process waits for the read finished in this
1059 * function. unless, the process does not wait and exit function.
1060 *
1061 * \param context
1062 * Passes a configuration structure that contains the transfer parameters of the
1063 * SMIF block.
1064 *
1065 * \return \ref cy_en_smif_status_t
1066 *
1067 *******************************************************************************/
Cy_SMIF_HyperBus_MMIO_Write(SMIF_Type * base,cy_en_smif_slave_select_t slave,cy_en_hb_burst_type_t burstType,uint32_t writeAddress,uint32_t sizeInHalfWord,uint16_t buf[],cy_en_smif_hb_dev_type_t hbDevType,uint32_t dummyCycle,bool isblockingMode,cy_stc_smif_context_t * context)1068 cy_en_smif_status_t Cy_SMIF_HyperBus_MMIO_Write(SMIF_Type *base,
1069 cy_en_smif_slave_select_t slave,
1070 cy_en_hb_burst_type_t burstType,
1071 uint32_t writeAddress,
1072 uint32_t sizeInHalfWord,
1073 uint16_t buf[],
1074 cy_en_smif_hb_dev_type_t hbDevType,
1075 uint32_t dummyCycle,
1076 bool isblockingMode,
1077 cy_stc_smif_context_t *context)
1078 {
1079 cy_en_smif_status_t status;
1080 (void)hbDevType;
1081
1082 uint32_t pageAddr = ((uint32_t)(writeAddress >> 3u) & 0x00FFFFFFU);
1083 uint16_t addr_first_2bytes = (uint16_t)(pageAddr);
1084 // THis is the last 8 bits of the 24 bit address. this should go in as part of command
1085 uint8_t addr_last_byte = (uint8_t)((pageAddr >> 16u));
1086
1087 uint32_t address = (uint32_t)( _VAL2FLD(SMIF_HYPERBUS_ADR_LOWER_COL_ADDRESS, writeAddress) |
1088 _VAL2FLD(SMIF_HYPERBUS_ADR_BYTE_ENABLE, 0x0U) |
1089 _VAL2FLD(SMIF_HYPERBUS_ADR_ROW_AND_UPPER_COL_ADDRESS, addr_first_2bytes));
1090 uint32_t revOfAddr = Cy_SMIF_Reverse4ByteEndian(address);
1091
1092 uint8_t param_addr[4];
1093 ValueToByteArray(revOfAddr, param_addr, 0u, 4U);
1094 uint16_t cmd = (uint16_t)( _VAL2FLD(SMIF_HYPERBUS_CMD_ADDRESS_LAST_BYTE, addr_last_byte) |
1095 _VAL2FLD(SMIF_HYPERBUS_CMD_BURST_TYPE, burstType) |
1096 _VAL2FLD(SMIF_HYPERBUS_CMD_TARGET_TYPE, CY_SMIF_HB_TARGET_MEMORY) |
1097 _VAL2FLD(SMIF_HYPERBUS_CMD_READ_WRITE, CY_SMIF_HB_WRITE));
1098
1099 /****** Command and Address ******/
1100 status = Cy_SMIF_TransmitCommand_Ext(base,
1101 cmd,
1102 true,
1103 CY_SMIF_WIDTH_OCTAL,
1104 CY_SMIF_DDR,
1105 (uint8_t*)&revOfAddr,
1106 4u,
1107 CY_SMIF_WIDTH_OCTAL,
1108 CY_SMIF_DDR,
1109 slave,
1110 CY_SMIF_TX_NOT_LAST_BYTE,
1111 context);
1112 if(status != CY_SMIF_SUCCESS)
1113 {
1114 return status;
1115 }
1116
1117 if(hbDevType == CY_SMIF_HB_SRAM)
1118 {
1119 if(dummyCycle > 0u)
1120 {
1121 #if (CY_IP_MXSMIF_VERSION>=2)
1122 status = Cy_SMIF_SendDummyCycles_With_RWDS(base, false, false, dummyCycle - 1U);
1123 #else
1124 status = Cy_SMIF_SendDummyCycles_Ext(base, CY_SMIF_WIDTH_OCTAL, CY_SMIF_DDR, dummyCycle - 1U);
1125 #endif
1126
1127 if(status != CY_SMIF_SUCCESS)
1128 {
1129 return status;
1130 }
1131 }
1132 }
1133 if(isblockingMode)
1134 {
1135 status = Cy_SMIF_TransmitDataBlocking_Ext(base, (uint8_t *)buf, (sizeInHalfWord*2u), CY_SMIF_WIDTH_OCTAL, CY_SMIF_DDR, context);
1136 }
1137 else
1138 {
1139 status = Cy_SMIF_TransmitData_Ext(base, (uint8_t const *)buf, (sizeInHalfWord*2u), CY_SMIF_WIDTH_OCTAL, CY_SMIF_DDR, NULL, context);
1140 }
1141
1142 return status;
1143 }
1144
1145 #if defined(__cplusplus)
1146 }
1147 #endif
1148 #endif /* defined (CY_IP_MXSMIF) && (CY_IP_MXSMIF_VERSION>=2) && (CY_IP_MXSMIF_VERSION <= 5) */
1149