1 /******************************************************************************
2 * Filename: ddi.c
3 * Revised: 2018-06-04 16:10:13 +0200 (Mon, 04 Jun 2018)
4 * Revision: 52111
5 *
6 * Description: Driver for the DDI master interface
7 *
8 * Copyright (c) 2015 - 2020, Texas Instruments Incorporated
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions are met:
13 *
14 * 1) Redistributions of source code must retain the above copyright notice,
15 * this list of conditions and the following disclaimer.
16 *
17 * 2) Redistributions in binary form must reproduce the above copyright notice,
18 * this list of conditions and the following disclaimer in the documentation
19 * and/or other materials provided with the distribution.
20 *
21 * 3) Neither the name of the ORGANIZATION nor the names of its contributors may
22 * be used to endorse or promote products derived from this software without
23 * specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
29 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGE.
36 *
37 ******************************************************************************/
38
39 #include "ddi.h"
40
41 //*****************************************************************************
42 //
43 // Handle support for DriverLib in ROM:
44 // This section will undo prototype renaming made in the header file
45 //
46 //*****************************************************************************
47 #if !defined(DOXYGEN)
48 #undef DDI32RegWrite
49 #define DDI32RegWrite NOROM_DDI32RegWrite
50 #undef DDI16BitWrite
51 #define DDI16BitWrite NOROM_DDI16BitWrite
52 #undef DDI16BitfieldWrite
53 #define DDI16BitfieldWrite NOROM_DDI16BitfieldWrite
54 #undef DDI16BitRead
55 #define DDI16BitRead NOROM_DDI16BitRead
56 #undef DDI16BitfieldRead
57 #define DDI16BitfieldRead NOROM_DDI16BitfieldRead
58 #endif
59
60 //*****************************************************************************
61 //
62 // Write a 32 bit value to a register in the DDI slave.
63 //
64 //*****************************************************************************
65 void
DDI32RegWrite(uint32_t ui32Base,uint32_t ui32Reg,uint32_t ui32Val)66 DDI32RegWrite(uint32_t ui32Base, uint32_t ui32Reg,
67 uint32_t ui32Val)
68 {
69 // Check the arguments.
70 ASSERT(DDIBaseValid(ui32Base));
71 ASSERT(ui32Reg < DDI_SLAVE_REGS);
72
73 // Write the value to the register.
74 HWREG(ui32Base + ui32Reg) = ui32Val;
75 }
76
77 //*****************************************************************************
78 //
79 // Write a single bit using a 16-bit maskable write
80 //
81 //*****************************************************************************
82 void
DDI16BitWrite(uint32_t ui32Base,uint32_t ui32Reg,uint32_t ui32Mask,uint32_t ui32WrData)83 DDI16BitWrite(uint32_t ui32Base, uint32_t ui32Reg,
84 uint32_t ui32Mask, uint32_t ui32WrData)
85 {
86 uint32_t ui32RegAddr;
87 uint32_t ui32Data;
88
89 // Check the arguments.
90 ASSERT(DDIBaseValid(ui32Base));
91 ASSERT(!((ui32Mask & 0xFFFF0000) ^ (ui32Mask & 0x0000FFFF)));
92 ASSERT(!(ui32WrData & 0xFFFF0000));
93
94 // DDI 16-bit target is on 32-bit boundary so double offset
95 ui32RegAddr = ui32Base + (ui32Reg << 1) + DDI_O_MASK16B;
96
97 // Adjust for target bit in high half of the word.
98 if(ui32Mask & 0xFFFF0000)
99 {
100 ui32RegAddr += 4;
101 ui32Mask >>= 16;
102 }
103
104 // Write mask if data is not zero (to set mask bit), else write '0'.
105 ui32Data = ui32WrData ? ui32Mask : 0x0;
106
107 // Update the register.
108 HWREG(ui32RegAddr) = (ui32Mask << 16) | ui32Data;
109 }
110
111 //*****************************************************************************
112 //
113 // Write a bit field via the DDI using 16-bit maskable write
114 //
115 //*****************************************************************************
116 void
DDI16BitfieldWrite(uint32_t ui32Base,uint32_t ui32Reg,uint32_t ui32Mask,uint32_t ui32Shift,uint16_t ui32Data)117 DDI16BitfieldWrite(uint32_t ui32Base, uint32_t ui32Reg,
118 uint32_t ui32Mask, uint32_t ui32Shift,
119 uint16_t ui32Data)
120 {
121 uint32_t ui32RegAddr;
122 uint32_t ui32WrData;
123
124 // Check the arguments.
125 ASSERT(DDIBaseValid(ui32Base));
126
127 // 16-bit target is on 32-bit boundary so double offset.
128 ui32RegAddr = ui32Base + (ui32Reg << 1) + DDI_O_MASK16B;
129
130 // Adjust for target bit in high half of the word.
131 if(ui32Shift >= 16)
132 {
133 ui32Shift = ui32Shift - 16;
134 ui32RegAddr += 4;
135 ui32Mask = ui32Mask >> 16;
136 }
137
138 // Shift data in to position.
139 ui32WrData = ui32Data << ui32Shift;
140
141 // Write data.
142 HWREG(ui32RegAddr) = (ui32Mask << 16) | ui32WrData;
143 }
144
145 //*****************************************************************************
146 //
147 // Read a bit via the DDI using 16-bit READ.
148 //
149 //*****************************************************************************
150 uint16_t
DDI16BitRead(uint32_t ui32Base,uint32_t ui32Reg,uint32_t ui32Mask)151 DDI16BitRead(uint32_t ui32Base, uint32_t ui32Reg, uint32_t ui32Mask)
152 {
153 uint32_t ui32RegAddr;
154 uint16_t ui16Data;
155
156 // Check the arguments.
157 ASSERT(DDIBaseValid(ui32Base));
158
159 // Calculate the address of the register.
160 ui32RegAddr = ui32Base + ui32Reg + DDI_O_DIR;
161
162 // Adjust for target bit in high half of the word.
163 if(ui32Mask & 0xFFFF0000)
164 {
165 ui32RegAddr += 2;
166 ui32Mask = ui32Mask >> 16;
167 }
168
169 // Read a halfword on the DDI interface.
170 ui16Data = HWREGH(ui32RegAddr);
171
172 // Mask data.
173 ui16Data = ui16Data & ui32Mask;
174
175 // Return masked data.
176 return(ui16Data);
177 }
178
179 //*****************************************************************************
180 //
181 // Read a bit field via the DDI using 16-bit read.
182 //
183 //*****************************************************************************
184 uint16_t
DDI16BitfieldRead(uint32_t ui32Base,uint32_t ui32Reg,uint32_t ui32Mask,uint32_t ui32Shift)185 DDI16BitfieldRead(uint32_t ui32Base, uint32_t ui32Reg,
186 uint32_t ui32Mask, uint32_t ui32Shift)
187 {
188 uint32_t ui32RegAddr;
189 uint16_t ui16Data;
190
191 // Check the arguments.
192 ASSERT(DDIBaseValid(ui32Base));
193
194 // Calculate the register address.
195 ui32RegAddr = ui32Base + ui32Reg + DDI_O_DIR;
196
197 // Adjust for target bit in high half of the word.
198 if(ui32Shift >= 16)
199 {
200 ui32Shift = ui32Shift - 16;
201 ui32RegAddr += 2;
202 ui32Mask = ui32Mask >> 16;
203 }
204
205 // Read the register.
206 ui16Data = HWREGH(ui32RegAddr);
207
208 // Mask data and shift into place.
209 ui16Data &= ui32Mask;
210 ui16Data >>= ui32Shift;
211
212 // Return data.
213 return(ui16Data);
214 }
215