1 /*
2  * Copyright (c) 2016, Freescale Semiconductor, Inc.
3  * Copyright 2016-2017 NXP
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 
9 #include "fsl_fmc.h"
10 
11 /*******************************************************************************
12  * Definitions
13  ******************************************************************************/
14 
15 /* Component ID definition, used by tools. */
16 #ifndef FSL_COMPONENT_ID
17 #define FSL_COMPONENT_ID "platform.drivers.fmc"
18 #endif
19 
20 /*******************************************************************************
21  * Prototypes
22  ******************************************************************************/
23 
24 /*******************************************************************************
25  * Variables
26  ******************************************************************************/
27 
28 /*******************************************************************************
29  * Code
30  ******************************************************************************/
31 
32 /*!
33  * brief Provides default configuration for fmc module.
34  *
35  * This function provides default configuration for fmc module, the default wait states value is
36  * 5.
37  *
38  * param config pointer to user configuration structure.
39  */
FMC_GetDefaultConfig(fmc_config_t * config)40 void FMC_GetDefaultConfig(fmc_config_t *config)
41 {
42     /* Initializes the configure structure to zero. */
43     (void)memset(config, 0, sizeof(*config));
44 
45     config->waitStates = 0x05;
46 }
47 
48 /*!
49  * brief Initialize FMC module.
50  *
51  * This function initialize FMC module with user configuration
52  *
53  * param base The FMC peripheral base address.
54  * param config pointer to user configuration structure.
55  */
FMC_Init(FMC_Type * base,fmc_config_t * config)56 void FMC_Init(FMC_Type *base, fmc_config_t *config)
57 {
58 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
59     /* enable clock to FMC */
60     CLOCK_EnableClock(kCLOCK_Fmc);
61 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
62 
63     /* Set control register, FS_RD0 = 0, FS_RD1 = 1. */
64     base->FCTR &= ~(FMC_FCTR_FS_RD0_MASK | FMC_FCTR_FS_RD1_MASK);
65     base->FCTR |= FMC_FCTR_FS_RD1_MASK;
66 
67     /* Set wait state, same as FLASHTIM in SYSCON->FLASHCFG register. */
68     base->FBWST &= ~FMC_FBWST_WAITSTATES_MASK;
69     base->FBWST |= config->waitStates;
70 }
71 
72 /*!
73  * brief Deinit FMC module.
74  *
75  * This function De-initialize FMC module.
76  *
77  * param base The FMC peripheral base address.
78  */
FMC_Deinit(FMC_Type * base)79 void FMC_Deinit(FMC_Type *base)
80 {
81 #if !(defined(FSL_SDK_DISABLE_DRIVER_RESET_CONTROL) && FSL_SDK_DISABLE_DRIVER_RESET_CONTROL)
82     /* Reset the module. */
83     RESET_PeripheralReset(kFMC_RST_SHIFT_RSTn);
84 #endif /* FSL_SDK_DISABLE_DRIVER_RESET_CONTROL */
85 
86 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
87     /* enable clock to FMC */
88     CLOCK_DisableClock(kCLOCK_Fmc);
89 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
90 }
91 
92 /*!
93  * brief Generate hardware flash signature.
94  *
95  * This function generates hardware flash signature for specified address range.
96  *
97  * note This function needs to be excuted out of flash memory.
98  * param base The FMC peripheral base address.
99  * param startAddress Flash start address for signature generation.
100  * param length Length of address range.
101  * param flashSignature Pointer which stores the generated flash signarue.
102  */
FMC_GenerateFlashSignature(FMC_Type * base,uint32_t startAddress,uint32_t length,fmc_flash_signature_t * flashSignature)103 void FMC_GenerateFlashSignature(FMC_Type *base,
104                                 uint32_t startAddress,
105                                 uint32_t length,
106                                 fmc_flash_signature_t *flashSignature)
107 {
108     uint32_t stopAddress;
109 
110     /* Clear generation done flag. */
111     base->FMSTATCLR = kFMC_SignatureGenerationDoneFlag;
112 
113     /* Calculate flash stop address */
114     stopAddress = ((startAddress + length - 1UL) >> 4UL) & FMC_FMSSTOP_STOP_MASK;
115 
116     /* Calculate flash start address. */
117     startAddress = (startAddress >> 4UL) & FMC_FMSSTART_START_MASK;
118 
119     /* Start flash signature generation. */
120     base->FMSSTART = startAddress;
121     base->FMSSTOP  = stopAddress;
122 
123     base->FMSSTOP |= FMC_FMSSTOP_SIG_START_MASK;
124 
125     /* Wait for signature done. */
126     while ((base->FMSTAT & (uint32_t)kFMC_SignatureGenerationDoneFlag) != (uint32_t)kFMC_SignatureGenerationDoneFlag)
127     {
128     }
129 
130     /* Clear generation done flag. */
131     base->FMSTATCLR = kFMC_SignatureGenerationDoneFlag;
132 
133     /* Get the generated flash signature. */
134     flashSignature->word0 = base->FMSW[0];
135     flashSignature->word1 = base->FMSW[1];
136     flashSignature->word2 = base->FMSW[2];
137     flashSignature->word3 = base->FMSW[3];
138 
139     return;
140 }
141