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 /**
22  * @file       infoblock.h
23  * @brief      Infoblock interface
24  * @details
25  *      This driver can be used to interface with the infoblock,
26  *      reading and writing select locations.
27  */
28 
29 #ifndef LIBRARIES_PERIPHDRIVERS_INCLUDE_MAX32680_INFOBLOCK_H_
30 #define LIBRARIES_PERIPHDRIVERS_INCLUDE_MAX32680_INFOBLOCK_H_
31 
32 #ifdef __cplusplus
33 extern "C" {
34 #endif
35 
36 #if !defined(TRUE) || !defined(FALSE)
37 #define TRUE 1
38 #define FALSE 0
39 #endif
40 /**
41  * @defgroup    infoblock_access Information Block (OTP) read interface
42  * @brief       Read access for information block
43  * @{
44  */
45 
46 /**
47  * @defgroup    infoblock_defines Information Block defines
48  * @brief       Registers, Bit Masks and Bit Positions for the Infoblock.
49  * @details     Defines used for accessing the information block
50  * @{
51  */
52 
53 /**
54  * @brief MAX32655 and some other parts have 128-bit wide flash, but hardware treats it as 64-bits/8 bytes for checksum purposes
55  */
56 #define INFOBLOCK_LINE_SIZE 8
57 
58 /**
59  * @brief Checksum overhead (\#bytes) in an infoblock line, reduces amount of data that can be stored
60  */
61 #define INFOBLOCK_LINE_OVERHEAD 2
62 
63 /**
64  * @brief 8 bytes, arranged as 4 16-bit uints
65  */
66 #define INFOBLOCK_ICE_LOCK_SIZE 8
67 
68 /**
69  * @brief MAX32655 has 128-bit wide flash so the permanent line lock bit is at the top of every 16 bytes
70  */
71 #define INFOBLOCK_WRITE_LOCK_LINE_SIZE 16
72 
73 /**
74  * @brief Unprogrammed flash reads as all 0xFF
75  */
76 #define ICELOCK_UNMODIFIED_VALUE 0xFFFF
77 
78 /**
79  * @brief The value hardware looks for to lock the SWD in even numbered 16-bit locations (0-based so locations 0 and 2).
80  */
81 #define ICELOCK_EVEN_LOCK_VALUE 0xA5A5
82 
83 /**
84  * @brief The value hardware looks for to lock the SWD in odd numbered 16-bit locations (0-based so locations 1 and 3)
85  */
86 #define ICELOCK_ODD_LOCK_VALUE 0x5A5A
87 
88 /**
89  * @brief Maximum information block read size.  Used in infoblock_read() to
90  *  set upper limit on bytes read.
91  */
92 #define INFOBLOCK_MAXIMUM_READ_LENGTH 64
93 
94 /**
95  * @brief The offset inside the information block where the USN (Universal Serial Number) is stored
96  */
97 #define INFOBLOCK_USN_OFFSET 0x00
98 
99 /**
100  * @brief The offset inside the information block where the SWD locking information is stored
101  * @note There are four locking locations starting at 0x30 for location 0, 0x32 for location 1, 0x34 for location 2, and 0x36 for location 3
102  */
103 #define INFOBLOCK_ICE_LOCK_OFFSET 0x30
104 
105 /**
106  * @brief The minimum number of locations with a lock value to cause SWD to be locked out.
107  */
108 #define INFOBLOCK_ICE_LOCK_MINIMUM 1
109 
110 /**
111  * @brief The offset inside the information block for Storage of ECDSA public key
112  */
113 #define INFOBLOCK_KEY_OFFSET 0x1000
114 /**
115  * @brief The length in bytes of the ECDSA public key
116  * @note This is the raw length. Once stored, 2 of every 8 bytes is used for CRC15, so the stored length is greater than 64 bytes.
117  */
118 #define INFOBLOCK_KEY_SIZE 64
119 
120 /**
121  * @brief Storage locations for feature enables.
122  *  The value 0x5a5aa5a5_5a5aa5a5 designates enable or disable depending on the function.
123  *  No CRC15 format in this case.
124  */
125 #define INFOBLOCK_ENABLE_SIZE (8)
126 
127 /**
128  * @brief Standard information block enable/disable pattern is 0x5A5AA5A5
129  */
130 #define INFOBLOCK_ENABLE_PATTERN 0x5A5AA5A5
131 
132 /**
133  * @brief Three information block line types
134  *
135  *  USN: No CRC15, ignore lowest 15 bits [14:0]
136  *
137  *  RAW: No CRC15
138  *
139  *  DESIGN: Use CRC15 error detection in bits [62:48].
140  */
141 typedef enum {
142     INFOBLOCK_LINE_FORMAT_USN, /**< USN format is unique, ignore lowest 15 bits */
143     INFOBLOCK_LINE_FORMAT_RAW, /**< Raw data format, use all bits */
144     INFOBLOCK_LINE_FORMAT_DESIGN, /**< Design format, has CRC15 in bits 62:48, bit 63 is a line locking bit */
145 } lineformat_e;
146 
147 /**@} end of group infoblock_defines */
148 
149 /**
150  * @brief crc15_highbitinput    Calculate CRC15 on data bits
151  * @param[out]  crc15val    Calling routine must supply a pointer to an array of at least 32 btyes. The hash digest will be placed there.
152  * @param[in]   input       pointer to the array of data to CRC15
153  * @param[in]   bitlength   length in bits of the data to CRC15
154  * @return      crc15val
155  */
156 uint16_t crc15_highbitinput(uint16_t crc15val, uint8_t *input, int bitlength);
157 
158 /**
159  * @brief infoblock_readraw    Read raw data from information block
160  * @param[in]   offset  location in the infoblock to read, this is a relative offset
161  * @param[out]  data    pointer to array where data will be stored.
162  * @return      error_code    error if unable to access infoblock
163  * @retval      E_NO_ERROR    read was successful
164  */
165 int infoblock_readraw(uint32_t offset, uint8_t *data);
166 
167 /**
168  * @brief infoblock_read    Read formatted data from information block
169  * @note        This routine uses the offest to determine the format of the data,
170  *              and will read the correct number of raw bytes be able to return
171  *              the number of data bytes specified. The CRC15 and formatting will
172  *              be removed and the data returned.
173  * @param[in]   offset  location in the infoblock to read, this is a relative offset
174  * @param[out]  data    pointer to array where data will be stored.
175  * @param[in]   length  number of bytes to read
176  * @return      error_code    error if unable to access infoblock
177  * @retval      E_NO_ERROR    read was successful
178  * @retval      E_BAD_PARAM   if incorrect length or offset is supplied
179  */
180 int infoblock_read(uint32_t offset, uint8_t *data, int length);
181 
182 /**@} end of group infoblock_access */
183 
184 #ifdef __cplusplus
185 }
186 #endif
187 
188 #endif // LIBRARIES_PERIPHDRIVERS_INCLUDE_MAX32680_INFOBLOCK_H_
189