1 /******************************************************************************
2 *
3 * Copyright (C) 2022-2023 Maxim Integrated Products, Inc. (now owned by
4 * Analog Devices, Inc.),
5 * Copyright (C) 2023-2024 Analog Devices, Inc.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 ******************************************************************************/
20
21 /* **** Includes **** */
22 #include <stdint.h>
23 #include "mxc_sys.h"
24 #include "mxc_errors.h"
25 #include "mxc_device.h"
26 #include "mxc_assert.h"
27 #include "otp.h"
28 #include "otp_reva.h"
29
30 /* **** Functions **** */
31
MXC_OTP_Init(mxc_otp_clkdiv_t pclkdiv)32 int MXC_OTP_Init(mxc_otp_clkdiv_t pclkdiv)
33 {
34 int lowest_pclkdiv_int;
35 int lowest_pclkdiv_dec;
36
37 // Divide by 16 is default divider value.
38 if (pclkdiv < MXC_OTP_CLK_DIV2 || pclkdiv > MXC_OTP_CLK_DIV32) {
39 pclkdiv = MXC_OTP_CLK_DIV16;
40 }
41
42 MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_OTP);
43
44 // Note: mxc_otp_clkdiv_t values based on predefined register definitions.
45
46 // Verify minimum timing requirement for OTP Controller. (>=400ns) Check UG.
47 // Note: mxc_otp_clkdiv_t values based on predefined register definitions.
48 // For example: pclkdiv = MXC_OTP_CLK_DIV2 = 0x01
49 // Divider value = pclkdiv + 1
50 // Divide by 2 = MXC_OTP_CLK_DIV2 + 1 = 0x01 + 1
51 lowest_pclkdiv_int = (PeripheralClock / 2500000); // (1 / (400ns)) = 2,500,000
52
53 // Do not truncate down if equation above doesn't perfectly divide out.
54 lowest_pclkdiv_dec = (100 * PeripheralClock / 2500000) - lowest_pclkdiv_int;
55 if (lowest_pclkdiv_dec > 0) {
56 lowest_pclkdiv_int += 1;
57 }
58
59 // Get raw clkdiv value. Divider value = pclkdiv + 1
60 lowest_pclkdiv_int -= 1;
61
62 if (pclkdiv < lowest_pclkdiv_int) {
63 return E_BAD_PARAM;
64 }
65
66 return MXC_OTP_RevA_Init((mxc_otp_reva_regs_t *)MXC_OTP, pclkdiv);
67 }
68
MXC_OTP_IsLocked(void)69 int MXC_OTP_IsLocked(void)
70 {
71 return MXC_OTP_RevA_IsLocked((mxc_otp_reva_regs_t *)MXC_OTP);
72 }
73
MXC_OTP_Unlock(void)74 void MXC_OTP_Unlock(void)
75 {
76 MXC_OTP_RevA_Unlock((mxc_otp_reva_regs_t *)MXC_OTP);
77 }
78
MXC_OTP_Lock(void)79 void MXC_OTP_Lock(void)
80 {
81 MXC_OTP_RevA_Lock((mxc_otp_reva_regs_t *)MXC_OTP);
82 }
83
MXC_OTP_Write(uint16_t addr,uint32_t * data,uint16_t size)84 int MXC_OTP_Write(uint16_t addr, uint32_t *data, uint16_t size)
85 {
86 return MXC_OTP_RevA_Write((mxc_otp_reva_regs_t *)MXC_OTP, addr, data, size);
87 }
88
MXC_OTP_Write32(uint16_t addr,uint32_t data)89 int MXC_OTP_Write32(uint16_t addr, uint32_t data)
90 {
91 return MXC_OTP_RevA_Write32((mxc_otp_reva_regs_t *)MXC_OTP, addr, data);
92 }
93
MXC_OTP_Read(uint16_t addr,uint32_t * data,uint16_t size)94 int MXC_OTP_Read(uint16_t addr, uint32_t *data, uint16_t size)
95 {
96 return MXC_OTP_RevA_Read((mxc_otp_reva_regs_t *)MXC_OTP, addr, data, size);
97 }
98
MXC_OTP_Read32(uint16_t addr,uint32_t * data)99 int MXC_OTP_Read32(uint16_t addr, uint32_t *data)
100 {
101 return MXC_OTP_RevA_Read32((mxc_otp_reva_regs_t *)MXC_OTP, addr, data);
102 }
103