1 /******************************************************************************
2 *  Filename:       ddi.h
3 *
4 *  Description:    Defines and prototypes 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 //*****************************************************************************
38 //
39 //! \addtogroup analog_group
40 //! @{
41 //! \addtogroup ddi_api
42 //! @{
43 //
44 //*****************************************************************************
45 
46 #ifndef __DDI_H__
47 #define __DDI_H__
48 
49 //*****************************************************************************
50 //
51 // If building with a C++ compiler, make all of the definitions in this header
52 // have a C binding.
53 //
54 //*****************************************************************************
55 #ifdef __cplusplus
56 extern "C"
57 {
58 #endif
59 
60 #include <stdbool.h>
61 #include <stdint.h>
62 #include "../inc/hw_types.h"
63 #include "../inc/hw_memmap.h"
64 #include "../inc/hw_ddi.h"
65 #include "../inc/hw_aux_smph.h"
66 #include "debug.h"
67 #include "cpu.h"
68 
69 //*****************************************************************************
70 //
71 // Support for DriverLib in ROM:
72 // This section renames all functions that are not "static inline", so that
73 // calling these functions will default to implementation in flash. At the end
74 // of this file a second renaming will change the defaults to implementation in
75 // ROM for available functions.
76 //
77 // To force use of the implementation in flash, e.g. for debugging:
78 // - Globally: Define DRIVERLIB_NOROM at project level
79 // - Per function: Use prefix "NOROM_" when calling the function
80 //
81 //*****************************************************************************
82 #if !defined(DOXYGEN)
83     #define DDI32RegWrite                   NOROM_DDI32RegWrite
84     #define DDI16BitWrite                   NOROM_DDI16BitWrite
85     #define DDI16BitfieldWrite              NOROM_DDI16BitfieldWrite
86     #define DDI16BitRead                    NOROM_DDI16BitRead
87     #define DDI16BitfieldRead               NOROM_DDI16BitfieldRead
88 #endif
89 
90 //*****************************************************************************
91 //
92 // Number of register in the DDI slave
93 //
94 //*****************************************************************************
95 #define DDI_SLAVE_REGS          64
96 
97 
98 //*****************************************************************************
99 //
100 // Defines that is used to control the ADI slave and master
101 //
102 //*****************************************************************************
103 #define DDI_PROTECT         0x00000080
104 #define DDI_ACK             0x00000001
105 #define DDI_SYNC            0x00000000
106 
107 //*****************************************************************************
108 //
109 // API Functions and prototypes
110 //
111 //*****************************************************************************
112 
113 
114 //*****************************************************************************
115 //
116 // Helper functions
117 //
118 //*****************************************************************************
119 #ifdef DRIVERLIB_DEBUG
120 //*****************************************************************************
121 //
122 //! \internal
123 //!
124 //! \brief Check a DDI base address.
125 //!
126 //! This function determines if a DDI port base address is valid.
127 //!
128 //! \param ui32Base is the base address of the DDI port.
129 //!
130 //! \return Returns \c true if the base address is valid and \c false
131 //! otherwise.
132 //!
133 //! \endinternal
134 //
135 //*****************************************************************************
136 static bool
DDIBaseValid(uint32_t ui32Base)137 DDIBaseValid(uint32_t ui32Base)
138 {
139     return(ui32Base == AUX_DDI0_OSC_BASE);
140 }
141 #endif
142 
143 
144 //*****************************************************************************
145 //
146 //! \brief Read the value in a 32 bit register.
147 //!
148 //! This function will read a register in the analog domain and return
149 //! the value as an \c uint32_t.
150 //!
151 //! \param ui32Base is DDI base address.
152 //! \param ui32Reg is the 32 bit register to read.
153 //!
154 //! \return Returns the 32 bit value of the analog register.
155 //
156 //*****************************************************************************
157 __STATIC_INLINE uint32_t
DDI32RegRead(uint32_t ui32Base,uint32_t ui32Reg)158 DDI32RegRead(uint32_t ui32Base, uint32_t ui32Reg)
159 {
160     // Check the arguments.
161     ASSERT(DDIBaseValid(ui32Base));
162     ASSERT(ui32Reg < DDI_SLAVE_REGS);
163 
164     // Read the register and return the value.
165     return(HWREG(ui32Base + ui32Reg));
166 }
167 
168 //*****************************************************************************
169 //
170 //! \brief Set specific bits in a DDI slave register.
171 //!
172 //! This function will set bits in a register in the analog domain.
173 //!
174 //! \note This operation is write only for the specified register.
175 //! This function is used to set bits in specific register in the
176 //! DDI slave. Only bits in the selected register are affected by the
177 //! operation.
178 //!
179 //! \param ui32Base is DDI base address.
180 //! \param ui32Reg is the base register to assert the bits in.
181 //! \param ui32Val is the 32 bit one-hot encoded value specifying which
182 //! bits to set in the register.
183 //!
184 //! \return None
185 //
186 //*****************************************************************************
187 __STATIC_INLINE void
DDI32BitsSet(uint32_t ui32Base,uint32_t ui32Reg,uint32_t ui32Val)188 DDI32BitsSet(uint32_t ui32Base, uint32_t ui32Reg, uint32_t ui32Val)
189 {
190     uint32_t ui32RegOffset;
191 
192     // Check the arguments.
193     ASSERT(DDIBaseValid(ui32Base));
194     ASSERT(ui32Reg < DDI_SLAVE_REGS);
195 
196     // Get the correct address of the first register used for setting bits
197     // in the DDI slave.
198     ui32RegOffset = DDI_O_SET;
199 
200     // Set the selected bits.
201     HWREG(ui32Base + ui32RegOffset + ui32Reg) = ui32Val;
202 }
203 
204 //*****************************************************************************
205 //
206 //! \brief Clear specific bits in a 32 bit DDI register.
207 //!
208 //! This function will clear bits in a register in the analog domain.
209 //!
210 //! \param ui32Base is DDI base address.
211 //! \param ui32Reg is the base registers to clear the bits in.
212 //! \param ui32Val is the 32 bit one-hot encoded value specifying which
213 //! bits to clear in the register.
214 //!
215 //! \return None
216 //
217 //*****************************************************************************
218 __STATIC_INLINE void
DDI32BitsClear(uint32_t ui32Base,uint32_t ui32Reg,uint32_t ui32Val)219 DDI32BitsClear(uint32_t ui32Base, uint32_t ui32Reg,
220                uint32_t ui32Val)
221 {
222     uint32_t ui32RegOffset;
223 
224     // Check the arguments.
225     ASSERT(DDIBaseValid(ui32Base));
226     ASSERT(ui32Reg < DDI_SLAVE_REGS);
227 
228     // Get the correct address of the first register used for setting bits
229     // in the DDI slave.
230     ui32RegOffset = DDI_O_CLR;
231 
232     // Clear the selected bits.
233     HWREG(ui32Base + ui32RegOffset + ui32Reg) = ui32Val;
234 }
235 
236 //*****************************************************************************
237 //
238 //! \brief Set a value on any 8 bits inside a 32 bit register in the DDI slave.
239 //!
240 //! This function allows byte (8 bit access) to the DDI slave registers.
241 //!
242 //! Use this function to write any value in the range 0-7 bits aligned on a
243 //! byte boundary. For example, for writing the value 0b101 to bits 1-3 set
244 //! <tt>ui16Val = 0x0A</tt> and <tt>ui16Mask = 0x0E</tt>. Bits 0 and 5-7 will
245 //! not be affected by the operation, as long as the corresponding bits are
246 //! not set in the \c ui16Mask.
247 //!
248 //! \param ui32Base is the base address of the DDI port.
249 //! \param ui32Reg is the Least Significant Register in the DDI slave that
250 //! will be affected by the write operation.
251 //! \param ui32Byte is the byte number to access within the 32 bit register.
252 //! \param ui16Mask is the mask defining which of the 8 bits that should be
253 //! overwritten. The mask must be defined in the lower half of the 16 bits.
254 //! \param ui16Val is the value to write. The value must be defined in the lower
255 //! half of the 16 bits.
256 //!
257 //! \return None
258 //
259 //*****************************************************************************
260 __STATIC_INLINE void
DDI8SetValBit(uint32_t ui32Base,uint32_t ui32Reg,uint32_t ui32Byte,uint16_t ui16Mask,uint16_t ui16Val)261 DDI8SetValBit(uint32_t ui32Base, uint32_t ui32Reg, uint32_t ui32Byte,
262               uint16_t ui16Mask, uint16_t ui16Val)
263 {
264     uint32_t ui32RegOffset;
265 
266     // Check the arguments.
267     ASSERT(DDIBaseValid(ui32Base));
268     ASSERT(ui32Reg < DDI_SLAVE_REGS);
269     ASSERT(!(ui16Val & 0xFF00));
270     ASSERT(!(ui16Mask & 0xFF00));
271 
272     // Get the correct address of the first register used for setting bits
273     // in the DDI slave.
274     ui32RegOffset = DDI_O_MASK8B + (ui32Reg << 1) + (ui32Byte << 1);
275 
276     // Set the selected bits.
277     HWREGH(ui32Base + ui32RegOffset) = (ui16Mask << 8) | ui16Val;
278 }
279 
280 //*****************************************************************************
281 //
282 //! \brief Set a value on any 16 bits inside a 32 bit register aligned on a
283 //! half-word boundary in the DDI slave.
284 //!
285 //! This function allows 16 bit masked access to the DDI slave registers.
286 //!
287 //! Use this function to write any value in the range 0-15 bits aligned on a
288 //! half-word boundary. For example, for writing the value 0b101 to bits 1-3 set
289 //! <tt>ui32Val = 0x000A</tt> and <tt>ui32Mask = 0x000E</tt>. Bits 0 and 5-15 will not be
290 //! affected by the operation, as long as the corresponding bits are not set
291 //! in the \c ui32Mask.
292 //!
293 //! \param ui32Base is the base address of the DDI port.
294 //! \param ui32Reg is register to access.
295 //! \param bWriteHigh defines which part of the register to write in.
296 //! \param ui32Mask is the mask defining which of the 16 bit that should be
297 //! overwritten. The mask must be defined in the lower half of the 32 bits.
298 //! \param ui32Val is the value to write. The value must be defined in the lower
299 //! half of the 32 bits.
300 //!
301 //! \return None
302 //
303 //*****************************************************************************
304 __STATIC_INLINE void
DDI16SetValBit(uint32_t ui32Base,uint32_t ui32Reg,bool bWriteHigh,uint32_t ui32Mask,uint32_t ui32Val)305 DDI16SetValBit(uint32_t ui32Base, uint32_t ui32Reg, bool bWriteHigh,
306                uint32_t ui32Mask, uint32_t ui32Val)
307 {
308     uint32_t ui32RegOffset;
309 
310     // Check the arguments.
311     ASSERT(DDIBaseValid(ui32Base));
312     ASSERT(ui32Reg < DDI_SLAVE_REGS);
313     ASSERT(!(ui32Val & 0xFFFF0000));
314     ASSERT(!(ui32Mask & 0xFFFF0000));
315 
316     // Get the correct address of the first register used for setting bits
317     // in the DDI slave.
318     ui32RegOffset = DDI_O_MASK16B + (ui32Reg << 1) + (bWriteHigh ? 4 : 0);
319 
320     // Set the selected bits.
321     HWREG(ui32Base + ui32RegOffset) = (ui32Mask << 16) | ui32Val;
322 }
323 
324 //*****************************************************************************
325 //
326 //! \brief Write a 32 bit value to a register in the DDI slave.
327 //!
328 //! This function will write a value to a register in the analog
329 //! domain.
330 //!
331 //! \note This operation is write only for the specified register. No
332 //! conservation of the previous value of the register will be kept (i.e. this
333 //! is NOT read-modify-write on the register).
334 //!
335 //! \param ui32Base is DDI base address.
336 //! \param ui32Reg is the register to write.
337 //! \param ui32Val is the 32 bit value to write to the register.
338 //!
339 //! \return None
340 //
341 //*****************************************************************************
342 extern void DDI32RegWrite(uint32_t ui32Base, uint32_t ui32Reg, uint32_t ui32Val);
343 
344 //*****************************************************************************
345 //
346 //! \brief Write a single bit using a 16-bit maskable write.
347 //!
348 //! A '1' is written to the bit if \c ui32WrData is non-zero, else a '0' is written.
349 //!
350 //! \param ui32Base is the base address of the DDI port.
351 //! \param ui32Reg is register to access.
352 //! \param ui32Mask is the mask defining which of the 16 bit that should be overwritten.
353 //! \param ui32WrData is the value to write. The value must be defined in the lower half of the 32 bits.
354 //!
355 //! \return None
356 //
357 //*****************************************************************************
358 extern void DDI16BitWrite(uint32_t ui32Base, uint32_t ui32Reg,
359                           uint32_t ui32Mask, uint32_t ui32WrData);
360 
361 
362 //*****************************************************************************
363 //
364 //! \brief Write a bit field via the DDI using 16-bit maskable write.
365 //!
366 //! Requires that entire bit field is within the half word boundary.
367 //!
368 //! \param ui32Base is the base address of the DDI port.
369 //! \param ui32Reg is register to access.
370 //! \param ui32Mask is the mask defining which of the 16 bits that should be overwritten.
371 //! \param ui32Shift is the shift value for the bit field.
372 //! \param ui32Data is the data aligned to bit 0.
373 //!
374 //! \return None
375 //
376 //*****************************************************************************
377 extern void DDI16BitfieldWrite(uint32_t ui32Base, uint32_t ui32Reg,
378                                uint32_t ui32Mask, uint32_t ui32Shift,
379                                uint16_t ui32Data);
380 
381 //*****************************************************************************
382 //
383 //! \brief Read a bit via the DDI using 16-bit read.
384 //!
385 //! \param ui32Base is the base address of the DDI module.
386 //! \param ui32Reg is the register to read.
387 //! \param ui32Mask defines the bit which should be read.
388 //!
389 //! \return Returns a zero if bit selected by mask is '0'. Else returns the mask.
390 //
391 //*****************************************************************************
392 extern uint16_t DDI16BitRead(uint32_t ui32Base, uint32_t ui32Reg,
393                              uint32_t ui32Mask);
394 
395 //*****************************************************************************
396 //
397 //! \brief Read a bit field via the DDI using 16-bit read.
398 //!
399 //! Requires that entire bit field is within the half word boundary.
400 //!
401 //! \param ui32Base is the base address of the DDI port.
402 //! \param ui32Reg is register to access.
403 //! \param ui32Mask is the mask defining which of the 16 bits that should be overwritten.
404 //! \param ui32Shift defines the required shift of the data to align with bit 0.
405 //!
406 //! \return Returns data aligned to bit 0.
407 //
408 //*****************************************************************************
409 extern uint16_t DDI16BitfieldRead(uint32_t ui32Base, uint32_t ui32Reg,
410                                   uint32_t ui32Mask, uint32_t ui32Shift);
411 
412 //*****************************************************************************
413 //
414 // Support for DriverLib in ROM:
415 // Redirect to implementation in ROM when available.
416 //
417 //*****************************************************************************
418 #if !defined(DRIVERLIB_NOROM) && !defined(DOXYGEN)
419     #include "../driverlib/rom.h"
420     #ifdef ROM_DDI32RegWrite
421         #undef  DDI32RegWrite
422         #define DDI32RegWrite                   ROM_DDI32RegWrite
423     #endif
424     #ifdef ROM_DDI16BitWrite
425         #undef  DDI16BitWrite
426         #define DDI16BitWrite                   ROM_DDI16BitWrite
427     #endif
428     #ifdef ROM_DDI16BitfieldWrite
429         #undef  DDI16BitfieldWrite
430         #define DDI16BitfieldWrite              ROM_DDI16BitfieldWrite
431     #endif
432     #ifdef ROM_DDI16BitRead
433         #undef  DDI16BitRead
434         #define DDI16BitRead                    ROM_DDI16BitRead
435     #endif
436     #ifdef ROM_DDI16BitfieldRead
437         #undef  DDI16BitfieldRead
438         #define DDI16BitfieldRead               ROM_DDI16BitfieldRead
439     #endif
440 #endif
441 
442 //*****************************************************************************
443 //
444 // Mark the end of the C bindings section for C++ compilers.
445 //
446 //*****************************************************************************
447 #ifdef __cplusplus
448 }
449 #endif
450 
451 #endif // __DDI_H__
452 
453 //*****************************************************************************
454 //
455 //! Close the Doxygen group.
456 //! @}
457 //! @}
458 //
459 //*****************************************************************************
460