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