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