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