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