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