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