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