summaryrefslogtreecommitdiffstats
path: root/bsps/arm/imxrt/mcux-sdk/drivers/ocotp/fsl_ocotp.h
blob: 73a405a12a04c66dc0b5af613e2bc8f8bd681440 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
/*
 * Copyright 2019-2020 NXP
 * All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */
#ifndef _FSL_OCOTP_H_
#define _FSL_OCOTP_H_

#include "fsl_common.h"

/*!
 * @addtogroup ocotp
 * @{
 */

/*******************************************************************************
 * Definitions
 *******************************************************************************/
/*! @name Driver version */
/*@{*/
/*! @brief OCOTP driver version. */
#define FSL_OCOTP_DRIVER_VERSION (MAKE_VERSION(2, 1, 3))
/*@}*/

#ifndef OCOTP_READ_FUSE_DATA_COUNT
#define OCOTP_READ_FUSE_DATA_COUNT (1U)
#endif

/*! @brief _ocotp_status Error codes for the OCOTP driver. */
enum
{
    kStatus_OCOTP_AccessError = MAKE_STATUS(kStatusGroup_SDK_OCOTP, 0), /*!< eFuse and shadow register access error. */
    kStatus_OCOTP_CrcFail     = MAKE_STATUS(kStatusGroup_SDK_OCOTP, 1), /*!< CRC check failed. */
    kStatus_OCOTP_ReloadError =
        MAKE_STATUS(kStatusGroup_SDK_OCOTP, 2), /*!< Error happens during reload shadow register. */
    kStatus_OCOTP_ProgramFail = MAKE_STATUS(kStatusGroup_SDK_OCOTP, 3), /*!< Fuse programming failed. */
    kStatus_OCOTP_Locked      = MAKE_STATUS(kStatusGroup_SDK_OCOTP, 4), /*!< Fuse is locked and cannot be programmed. */
};

#if (defined(FSL_FEATURE_OCOTP_HAS_TIMING_CTRL) && FSL_FEATURE_OCOTP_HAS_TIMING_CTRL)
/*! @brief OCOTP timing structure.
 *  Note that, these value are used for calcalating the read/write timings.
 *  And the values should statisfy below rules:
 *
 *  Tsp_rd=(WAIT+1)/ipg_clk_freq should be >= 150ns;
 *  Tsp_pgm=(RELAX+1)/ipg_clk_freq should be >= 100ns;
 *  Trd = ((STROBE_READ+1)- 2*(RELAX_READ+1)) /ipg_clk_freq,
 *  The Trd is required to be larger than 40 ns.
 *  Tpgm = ((STROBE_PROG+1)- 2*(RELAX_PROG+1)) /ipg_clk_freq;
 *  The Tpgm should be configured within the range of 9000 ns < Tpgm < 11000 ns;
 */
typedef struct _ocotp_timing
{
    uint32_t wait;        /*!< Wait time value to fill in the TIMING register. */
    uint32_t relax;       /*!< Relax time value to fill in the TIMING register. */
    uint32_t strobe_prog; /*!< Storbe program time value to fill in the TIMING register. */
    uint32_t strobe_read; /*!< Storbe read time value to fill in the TIMING register. */
} ocotp_timing_t;
#endif /* FSL_FEATURE_OCOTP_HAS_TIMING_CTRL */

/*******************************************************************************
 * API
 *******************************************************************************/

#if defined(__cplusplus)
extern "C" {
#endif

/*!
 * @brief Initializes OCOTP controller.
 *
 * @param base         OCOTP peripheral base address.
 * @param srcClock_Hz  source clock frequency in unit of Hz. When the macro
 * FSL_FEATURE_OCOTP_HAS_TIMING_CTRL is defined as 0, this parameter is not used,
 * application could pass in 0 in this case.
 */
void OCOTP_Init(OCOTP_Type *base, uint32_t srcClock_Hz);

/*!
 * @brief De-initializes OCOTP controller.
 *
 * @retval kStatus_Success upon successful execution, error status otherwise.
 */
void OCOTP_Deinit(OCOTP_Type *base);

/*!
 * @brief Checking the BUSY bit in CTRL register.
 * Checking this BUSY bit will help confirm if the OCOTP controller is ready for access.
 *
 * @param base         OCOTP peripheral base address.
 * @retval       true for bit set and false for cleared.
 */
static inline bool OCOTP_CheckBusyStatus(OCOTP_Type *base)
{
    return ((OCOTP_CTRL_BUSY_MASK == (base->CTRL & OCOTP_CTRL_BUSY_MASK)) ? (true) : (false));
}

/*!
 * @brief Checking the ERROR bit in CTRL register.
 *
 * @param base         OCOTP peripheral base address.
 * @retval       true for bit set and false for cleared.
 */
static inline bool OCOTP_CheckErrorStatus(OCOTP_Type *base)
{
    return ((OCOTP_CTRL_ERROR_MASK == (base->CTRL & OCOTP_CTRL_ERROR_MASK)) ? (true) : (false));
}

/*!
 * @brief Clear the error bit if this bit is set.
 *
 * @param base  OCOTP peripheral base address.
 */
static inline void OCOTP_ClearErrorStatus(OCOTP_Type *base)
{
    base->CTRL_CLR = OCOTP_CTRL_CLR_ERROR_MASK;
}

/*!
 * @brief Reload the shadow register.
 * This function will help reload the shadow register without reseting the OCOTP module.
 * Please make sure the OCOTP has been initialized before calling this API.
 *
 * @param base OCOTP peripheral base addess.
 * @retval kStatus_Success Reload success.
 * @retval kStatus_OCOTP_ReloadError Reload failed.
 */
status_t OCOTP_ReloadShadowRegister(OCOTP_Type *base);

/*!
 * @brief Read the fuse shadow register with the fuse addess.
 *
 * @deprecated Use @ref OCOTP_ReadFuseShadowRegisterExt instead of this function.
 *
 * @param base     OCOTP peripheral base address.
 * @param address  the fuse address to be read from.
 * @return The read out data.
 */
uint32_t OCOTP_ReadFuseShadowRegister(OCOTP_Type *base, uint32_t address);

/*!
 * @brief Read the fuse shadow register from the fuse addess.
 *
 * This function reads fuse from @p address, how many words to read is specified
 * by the parameter @p fuseWords. This function could read at most
 * OCOTP_READ_FUSE_DATA_COUNT fuse word one time.
 *
 * @param base     OCOTP peripheral base address.
 * @param address  the fuse address to be read from.
 * @param data     Data array to save the readout fuse value.
 * @param fuseWords How many words to read.
 * @retval kStatus_Success Read success.
 * @retval kStatus_Fail Error occurs during read.
 */
status_t OCOTP_ReadFuseShadowRegisterExt(OCOTP_Type *base, uint32_t address, uint32_t *data, uint8_t fuseWords);

/*!
 * @brief Write the fuse shadow register with the fuse addess and data.
 * Please make sure the wrtie address is not locked while calling this API.
 *
 * @param base     OCOTP peripheral base address.
 * @param address  the fuse address to be written.
 * @param data     the value will be writen to fuse address.
 * @retval   write status, kStatus_Success for success and kStatus_Fail for failed.
 */
status_t OCOTP_WriteFuseShadowRegister(OCOTP_Type *base, uint32_t address, uint32_t data);

/*!
 * @brief Write the fuse shadow register and lock it.
 *
 * Please make sure the wrtie address is not locked while calling this API.
 *
 * Some OCOTP controller supports ECC mode and redundancy mode (see reference mananual
 * for more details). OCOTP controller will auto select ECC or redundancy
 * mode to program the fuse word according to fuse map definition. In ECC mode, the
 * 32 fuse bits in one word can only be written once. In redundancy mode, the word can
 * be written more than once as long as they are different fuse bits. Set parameter
 * @p lock as true to force use ECC mode.
 *
 * @param base     OCOTP peripheral base address.
 * @param address  The fuse address to be written.
 * @param data     The value will be writen to fuse address.
 * @param lock     Lock or unlock write fuse shadow register operation.
 * @retval kStatus_Success Program and reload success.
 * @retval kStatus_OCOTP_Locked The eFuse word is locked and cannot be programmed.
 * @retval kStatus_OCOTP_ProgramFail eFuse word programming failed.
 * @retval kStatus_OCOTP_ReloadError eFuse word programming success, but
 *         error happens during reload the values.
 * @retval kStatus_OCOTP_AccessError Cannot access eFuse word.
 */
status_t OCOTP_WriteFuseShadowRegisterWithLock(OCOTP_Type *base, uint32_t address, uint32_t data, bool lock);

/*!
 * @brief Get the OCOTP controller version from the register.
 *
 * @param base    OCOTP peripheral base address.
 * @retval  return the version value.
 */
static inline uint32_t OCOTP_GetVersion(OCOTP_Type *base)
{
    return (base->VERSION);
}

#if defined(__cplusplus)
}
#endif

/*! @}*/

#endif /* _FSL_OCOTP_H_ */