1 /**
2 * @file flc_common.c
3 * @brief Common functions for the flash controller drivers.
4 * @details This driver can be used to operate on the embedded flash memory.
5 */
6 /******************************************************************************
7 *
8 * Copyright (C) 2022-2023 Maxim Integrated Products, Inc. (now owned by
9 * Analog Devices, Inc.),
10 * Copyright (C) 2023-2024 Analog Devices, Inc.
11 *
12 * Licensed under the Apache License, Version 2.0 (the "License");
13 * you may not use this file except in compliance with the License.
14 * You may obtain a copy of the License at
15 *
16 * http://www.apache.org/licenses/LICENSE-2.0
17 *
18 * Unless required by applicable law or agreed to in writing, software
19 * distributed under the License is distributed on an "AS IS" BASIS,
20 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21 * See the License for the specific language governing permissions and
22 * limitations under the License.
23 *
24 ******************************************************************************/
25
26 /* **** Includes **** */
27 #include <string.h>
28 #include "mxc_device.h"
29 #include "mxc_assert.h"
30 #include "mxc_sys.h"
31 #include "flc.h"
32 #include "flc_common.h"
33 #include "stdlib.h"
34
35 //******************************************************************************
36 #if IAR_PRAGMAS
37 #pragma section = ".flashprog"
38 #else
39 __attribute__((section(".flashprog")))
40 #endif
41 // Length is number of 32-bit words
MXC_FLC_Com_VerifyData(uint32_t address,uint32_t length,uint32_t * data)42 int MXC_FLC_Com_VerifyData(uint32_t address, uint32_t length, uint32_t *data)
43 {
44 volatile uint32_t *ptr;
45
46 for (ptr = (uint32_t *)address; ptr < (((uint32_t *)(address)) + length); ptr++, data++) {
47 if (*ptr != *data) {
48 return E_BAD_STATE;
49 }
50 }
51
52 return E_NO_ERROR;
53 }
54
55 //******************************************************************************
56 #if IAR_PRAGMAS
57 #pragma section = ".flashprog"
58 #else
59 __attribute__((section(".flashprog")))
60 #endif
61 // make sure to disable ICC with ICC_Disable(); before Running this function
MXC_FLC_Com_Write(uint32_t address,uint32_t length,uint32_t * buffer)62 int MXC_FLC_Com_Write(uint32_t address, uint32_t length, uint32_t *buffer)
63 {
64 int err;
65 uint32_t bytes_written;
66
67 uint32_t current_data_32;
68 uint8_t *current_data = (uint8_t *)¤t_data_32;
69 uint8_t *buffer8 = (uint8_t *)buffer;
70
71 // Align the address to a word boundary and read/write if we have to
72 if (address & 0x3) {
73 // Figure out how many bytes we have to write to round up the address
74 bytes_written = 4 - (address & 0x3);
75
76 // Save the data currently in the flash
77 memcpy(current_data, (void *)(address & (~0x3)), 4);
78
79 // Modify current_data to insert the data from buffer
80 memcpy(¤t_data[4 - bytes_written], buffer8, bytes_written);
81
82 // Write the modified data
83 if ((err = MXC_FLC_Write32(address - (address % 4), current_data_32)) != E_NO_ERROR) {
84 return err;
85 }
86
87 address += bytes_written;
88 length -= bytes_written;
89 buffer8 += bytes_written;
90 }
91
92 // Align the address to a 4-word (128bit) boundary
93 while ((length >= 4) && ((address & 0xF) != 0)) {
94 memcpy(current_data, buffer8, 4);
95 if ((err = MXC_FLC_Write32(address, current_data_32)) != E_NO_ERROR) {
96 return err;
97 }
98
99 address += 4;
100 length -= 4;
101 buffer8 += 4;
102 }
103
104 if (length >= 16) {
105 uint32_t buff128[4];
106 while (length >= 16) {
107 memcpy(buff128, buffer8, 16);
108 if ((err = MXC_FLC_Write128(address, buff128)) != E_NO_ERROR) {
109 return err;
110 }
111
112 address += 16;
113 length -= 16;
114 buffer8 += 16;
115 }
116 }
117
118 while (length >= 4) {
119 memcpy(current_data, buffer8, 4);
120 if ((err = MXC_FLC_Write32(address, current_data_32)) != E_NO_ERROR) {
121 return err;
122 }
123
124 address += 4;
125 length -= 4;
126 buffer8 += 4;
127 }
128
129 if (length > 0) {
130 // Save the data currently in the flash
131 memcpy(current_data, (void *)(address), 4);
132
133 // Modify current_data to insert the data from buffer
134 memcpy(current_data, buffer8, length);
135
136 if ((err = MXC_FLC_Write32(address, current_data_32)) != E_NO_ERROR) {
137 return err;
138 }
139 }
140
141 return E_NO_ERROR;
142 }
143
144 //******************************************************************************
145 #if IAR_PRAGMAS
146 #pragma section = ".flashprog"
147 #else
148 __attribute__((section(".flashprog")))
149 #endif
MXC_FLC_Com_Read(int address,void * buffer,int len)150 void MXC_FLC_Com_Read(int address, void *buffer, int len)
151 {
152 memcpy(buffer, (void *)address, len);
153 }
154