1 /******************************************************************************
2 * Filename: ddi.h
3 * Revised: 2015-07-16 12:12:04 +0200 (Thu, 16 Jul 2015)
4 * Revision: 44151
5 *
6 * Description: Defines and prototypes for the DDI master interface.
7 *
8 * Copyright (c) 2015, 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 <driverlib/debug.h>
69 #include <driverlib/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 DDI16BitWrite NOROM_DDI16BitWrite
86 #define DDI16BitfieldWrite NOROM_DDI16BitfieldWrite
87 #define DDI16BitRead NOROM_DDI16BitRead
88 #define DDI16BitfieldRead NOROM_DDI16BitfieldRead
89 #endif
90
91 //*****************************************************************************
92 //
93 // Number of register in the DDI slave
94 //
95 //*****************************************************************************
96 #define DDI_SLAVE_REGS 64
97
98
99 //*****************************************************************************
100 //
101 // Defines that is used to control the ADI slave and master
102 //
103 //*****************************************************************************
104 #define DDI_PROTECT 0x00000080
105 #define DDI_ACK 0x00000001
106 #define DDI_SYNC 0x00000000
107
108 //*****************************************************************************
109 //
110 // API Functions and prototypes
111 //
112 //*****************************************************************************
113
114
115 //*****************************************************************************
116 //
117 // Helper functions
118 //
119 //*****************************************************************************
120
121 //*****************************************************************************
122 //
123 //! \brief Safely write to AUX ADI/DDI interfaces using a semaphore.
124 //!
125 //! \note Both the AUX module and the clock for the AUX SMPH module must be
126 //! enabled before calling this function.
127 //!
128 //! \param nAddr is the register address.
129 //! \param nData is the data to write to the register.
130 //! \param nSize is the register access size in bytes.
131 //!
132 //! \return None
133 //
134 //*****************************************************************************
135 __STATIC_INLINE void
AuxAdiDdiSafeWrite(uint32_t nAddr,uint32_t nData,uint32_t nSize)136 AuxAdiDdiSafeWrite(uint32_t nAddr, uint32_t nData, uint32_t nSize)
137 {
138 // Disable interrupts and remember whether to re-enable
139 bool bIrqEnabled = !CPUcpsid();
140 // Acquire semaphore for accessing ADI/DDI in AUX, perform access, release semaphore
141 while (!HWREG(AUX_SMPH_BASE + AUX_SMPH_O_SMPH0));
142 switch (nSize) {
143 case 1: HWREGB(nAddr) = (uint8_t)nData; break;
144 case 2: HWREGH(nAddr) = (uint16_t)nData; break;
145 case 4: default: HWREG(nAddr) = nData; break;
146 }
147 HWREG(AUX_SMPH_BASE + AUX_SMPH_O_SMPH0) = 1;
148 // Restore interrupt enable
149 if (bIrqEnabled) {
150 CPUcpsie();
151 }
152 }
153
154 //*****************************************************************************
155 //
156 //! \brief Safely read from AUX ADI/DDI interfaces using a semaphore.
157 //!
158 //! \note Both the AUX module and the clock for the AUX SMPH module must be
159 //! enabled before calling this function.
160 //!
161 //! \param nAddr is the register address.
162 //! \param nSize is the register access size in bytes.
163 //!
164 //! \return Returns the data read.
165 //
166 //*****************************************************************************
167 __STATIC_INLINE uint32_t
AuxAdiDdiSafeRead(uint32_t nAddr,uint32_t nSize)168 AuxAdiDdiSafeRead(uint32_t nAddr, uint32_t nSize)
169 {
170 uint32_t nRet;
171 // Disable interrupts and remember whether to re-enable
172 bool bIrqEnabled = !CPUcpsid();
173 // Acquire semaphore for accessing ADI/DDI in AUX, perform access, release semaphore
174 while (!HWREG(AUX_SMPH_BASE + AUX_SMPH_O_SMPH0));
175 switch (nSize) {
176 case 1: nRet = HWREGB(nAddr); break;
177 case 2: nRet = HWREGH(nAddr); break;
178 case 4: default: nRet = HWREG(nAddr); break;
179 }
180 HWREG(AUX_SMPH_BASE + AUX_SMPH_O_SMPH0) = 1;
181 // Restore interrupt enable
182 if (bIrqEnabled) {
183 CPUcpsie();
184 }
185 return nRet;
186 }
187
188 #ifdef DRIVERLIB_DEBUG
189 //*****************************************************************************
190 //
191 //! \internal
192 //!
193 //! \brief Check a DDI base address.
194 //!
195 //! This function determines if a DDI port base address is valid.
196 //!
197 //! \param ui32Base is the base address of the DDI port.
198 //!
199 //! \return Returns \c true if the base address is valid and \c false
200 //! otherwise.
201 //!
202 //! \endinternal
203 //
204 //*****************************************************************************
205 static bool
DDIBaseValid(uint32_t ui32Base)206 DDIBaseValid(uint32_t ui32Base)
207 {
208 return(ui32Base == AUX_DDI0_OSC_BASE);
209 }
210 #endif
211
212
213 //*****************************************************************************
214 //
215 //! \brief Write a 32 bit value to a register in the DDI slave.
216 //!
217 //! This function will write a value to a register in the analog
218 //! domain.
219 //!
220 //! \note This operation is write only for the specified register. No
221 //! conservation of the previous value of the register will be kept (i.e. this
222 //! is NOT read-modify-write on the register).
223 //!
224 //! \note Both the AUX module and the clock for the AUX SMPH module must be
225 //! enabled before calling this function.
226 //!
227 //! \param ui32Base is DDI base address.
228 //! \param ui32Reg is the register to write.
229 //! \param ui32Val is the 32 bit value to write to the register.
230 //!
231 //! \return None
232 //
233 //*****************************************************************************
234 __STATIC_INLINE void
DDI32RegWrite(uint32_t ui32Base,uint32_t ui32Reg,uint32_t ui32Val)235 DDI32RegWrite(uint32_t ui32Base, uint32_t ui32Reg,
236 uint32_t ui32Val)
237 {
238 //
239 // Check the arguments.
240 //
241 ASSERT(DDIBaseValid(ui32Base));
242 ASSERT(ui32Reg < DDI_SLAVE_REGS);
243
244 //
245 // Write the value to the register.
246 //
247 AuxAdiDdiSafeWrite(ui32Base + ui32Reg, ui32Val, 4);
248 }
249
250 //*****************************************************************************
251 //
252 //! \brief Read the value in a 32 bit register.
253 //!
254 //! This function will read a register in the analog domain and return
255 //! the value as an \c uint32_t.
256 //!
257 //! \note Both the AUX module and the clock for the AUX SMPH module must be
258 //! enabled before calling this function.
259 //!
260 //! \param ui32Base is DDI base address.
261 //! \param ui32Reg is the 32 bit register to read.
262 //!
263 //! \return Returns the 32 bit value of the analog register.
264 //
265 //*****************************************************************************
266 __STATIC_INLINE uint32_t
DDI32RegRead(uint32_t ui32Base,uint32_t ui32Reg)267 DDI32RegRead(uint32_t ui32Base, uint32_t ui32Reg)
268 {
269 //
270 // Check the arguments.
271 //
272 ASSERT(DDIBaseValid(ui32Base));
273 ASSERT(ui32Reg < DDI_SLAVE_REGS);
274
275 //
276 // Read the register and return the value.
277 //
278 return AuxAdiDdiSafeRead(ui32Base + ui32Reg, 4);
279 }
280
281 //*****************************************************************************
282 //
283 //! \brief Set specific bits in a DDI slave register.
284 //!
285 //! This function will set bits in a register in the analog domain.
286 //!
287 //! \note This operation is write only for the specified register.
288 //! This function is used to set bits in specific register in the
289 //! DDI slave. Only bits in the selected register are affected by the
290 //! operation.
291 //!
292 //! \note Both the AUX module and the clock for the AUX SMPH module must be
293 //! enabled before calling this function.
294 //!
295 //! \param ui32Base is DDI base address.
296 //! \param ui32Reg is the base register to assert the bits in.
297 //! \param ui32Val is the 32 bit one-hot encoded value specifying which
298 //! bits to set in the register.
299 //!
300 //! \return None
301 //
302 //*****************************************************************************
303 __STATIC_INLINE void
DDI32BitsSet(uint32_t ui32Base,uint32_t ui32Reg,uint32_t ui32Val)304 DDI32BitsSet(uint32_t ui32Base, uint32_t ui32Reg, uint32_t ui32Val)
305 {
306 uint32_t ui32RegOffset;
307
308 //
309 // Check the arguments.
310 //
311 ASSERT(DDIBaseValid(ui32Base));
312 ASSERT(ui32Reg < DDI_SLAVE_REGS);
313
314 //
315 // Get the correct address of the first register used for setting bits
316 // in the DDI slave.
317 //
318 ui32RegOffset = DDI_O_SET;
319
320 //
321 // Set the selected bits.
322 //
323 AuxAdiDdiSafeWrite(ui32Base + ui32RegOffset + ui32Reg, ui32Val, 4);
324 }
325
326 //*****************************************************************************
327 //
328 //! \brief Clear specific bits in a 32 bit DDI register.
329 //!
330 //! This function will clear bits in a register in the analog domain.
331 //!
332 //! \note Both the AUX module and the clock for the AUX SMPH module must be
333 //! enabled before calling this function.
334 //!
335 //! \param ui32Base is DDI base address.
336 //! \param ui32Reg is the base registers to clear the bits in.
337 //! \param ui32Val is the 32 bit one-hot encoded value specifying which
338 //! bits to clear in the register.
339 //!
340 //! \return None
341 //
342 //*****************************************************************************
343 __STATIC_INLINE void
DDI32BitsClear(uint32_t ui32Base,uint32_t ui32Reg,uint32_t ui32Val)344 DDI32BitsClear(uint32_t ui32Base, uint32_t ui32Reg,
345 uint32_t ui32Val)
346 {
347 uint32_t ui32RegOffset;
348
349 //
350 // Check the arguments.
351 //
352 ASSERT(DDIBaseValid(ui32Base));
353 ASSERT(ui32Reg < DDI_SLAVE_REGS);
354
355 //
356 // Get the correct address of the first register used for setting bits
357 // in the DDI slave.
358 //
359 ui32RegOffset = DDI_O_CLR;
360
361 //
362 // Clear the selected bits.
363 //
364 AuxAdiDdiSafeWrite(ui32Base + ui32RegOffset + ui32Reg, ui32Val, 4);
365 }
366
367 //*****************************************************************************
368 //
369 //! \brief Set a value on any 8 bits inside a 32 bit register in the DDI slave.
370 //!
371 //! This function allows byte (8 bit access) to the DDI slave registers.
372 //!
373 //! Use this function to write any value in the range 0-7 bits aligned on a
374 //! byte boundary. Fx. for writing the value 0b101 to bits 1-3 set
375 //! <tt>ui16Val = 0x0A</tt> and <tt>ui16Mask = 0x0E</tt>. Bits 0 and 5-7 will
376 //! not be affected by the operation, as long as the corresponding bits are
377 //! not set in the \c ui16Mask.
378 //!
379 //! \note Both the AUX module and the clock for the AUX SMPH module must be
380 //! enabled before calling this function.
381 //!
382 //! \param ui32Base is the base address of the DDI port.
383 //! \param ui32Reg is the Least Significant Register in the DDI slave that
384 //! will be affected by the write operation.
385 //! \param ui32Byte is the byte number to access within the 32 bit register.
386 //! \param ui16Mask is the mask defining which of the 8 bits that should be
387 //! overwritten. The mask must be defined in the lower half of the 16 bits.
388 //! \param ui16Val is the value to write. The value must be defined in the lower
389 //! half of the 16 bits.
390 //!
391 //! \return None
392 //
393 //*****************************************************************************
394 __STATIC_INLINE void
DDI8SetValBit(uint32_t ui32Base,uint32_t ui32Reg,uint32_t ui32Byte,uint16_t ui16Mask,uint16_t ui16Val)395 DDI8SetValBit(uint32_t ui32Base, uint32_t ui32Reg, uint32_t ui32Byte,
396 uint16_t ui16Mask, uint16_t ui16Val)
397 {
398 uint32_t ui32RegOffset;
399
400 //
401 // Check the arguments.
402 //
403 ASSERT(DDIBaseValid(ui32Base));
404 ASSERT(ui32Reg < DDI_SLAVE_REGS);
405 ASSERT(!(ui16Val & 0xFF00));
406 ASSERT(!(ui16Mask & 0xFF00));
407
408 //
409 // Get the correct address of the first register used for setting bits
410 // in the DDI slave.
411 //
412 ui32RegOffset = DDI_O_MASK8B + (ui32Reg << 1) + (ui32Byte << 1);
413
414 //
415 // Set the selected bits.
416 //
417 AuxAdiDdiSafeWrite(ui32Base + ui32RegOffset, (ui16Mask << 8) | ui16Val, 2);
418 }
419
420 //*****************************************************************************
421 //
422 //! \brief Set a value on any 16 bits inside a 32 bit register aligned on a
423 //! half-word boundary in the DDI slave.
424 //!
425 //! This function allows 16 bit masked access to the DDI slave registers.
426 //!
427 //! Use this function to write any value in the range 0-15 bits aligned on a
428 //! half-word boundary. Fx. for writing the value 0b101 to bits 1-3 set
429 //! <tt>ui32Val = 0x000A</tt> and <tt>ui32Mask = 0x000E</tt>. Bits 0 and 5-15 will not be
430 //! affected by the operation, as long as the corresponding bits are not set
431 //! in the \c ui32Mask.
432 //!
433 //! \note Both the AUX module and the clock for the AUX SMPH module must be
434 //! enabled before calling this function.
435 //!
436 //! \param ui32Base is the base address of the DDI port.
437 //! \param ui32Reg is register to access.
438 //! \param bWriteHigh defines which part of the register to write in.
439 //! \param ui32Mask is the mask defining which of the 16 bit that should be
440 //! overwritten. The mask must be defined in the lower half of the 32 bits.
441 //! \param ui32Val is the value to write. The value must be defined in the lower
442 //! half of the 32 bits.
443 //!
444 //! \return None
445 //
446 //*****************************************************************************
447 __STATIC_INLINE void
DDI16SetValBit(uint32_t ui32Base,uint32_t ui32Reg,bool bWriteHigh,uint32_t ui32Mask,uint32_t ui32Val)448 DDI16SetValBit(uint32_t ui32Base, uint32_t ui32Reg, bool bWriteHigh,
449 uint32_t ui32Mask, uint32_t ui32Val)
450 {
451 uint32_t ui32RegOffset;
452
453 //
454 // Check the arguments.
455 //
456 ASSERT(DDIBaseValid(ui32Base));
457 ASSERT(ui32Reg < DDI_SLAVE_REGS);
458 ASSERT(!(ui32Val & 0xFFFF0000));
459 ASSERT(!(ui32Mask & 0xFFFF0000));
460
461 //
462 // Get the correct address of the first register used for setting bits
463 // in the DDI slave.
464 //
465 ui32RegOffset = DDI_O_MASK16B + (ui32Reg << 1) + (bWriteHigh ? 4 : 0);
466
467 //
468 // Set the selected bits.
469 //
470 AuxAdiDdiSafeWrite(ui32Base + ui32RegOffset, (ui32Mask << 16) | ui32Val, 4);
471 }
472
473 //*****************************************************************************
474 //
475 //! \brief Write a single bit using a 16-bit maskable write.
476 //!
477 //! A '1' is written to the bit if \c ui32WrData is non-zero, else a '0' is written.
478 //!
479 //! \note Both the AUX module and the clock for the AUX SMPH module must be
480 //! enabled before calling this function.
481 //!
482 //! \param ui32Base is the base address of the DDI port.
483 //! \param ui32Reg is register to access.
484 //! \param ui32Mask is the mask defining which of the 16 bit that should be
485 //! overwritten. The mask must be defined in the lower half of the 32 bits.
486 //! \param ui32WrData is the value to write. The value must be defined in the lower
487 //! half of the 32 bits.
488 //!
489 //! \return None
490 //
491 //*****************************************************************************
492 extern void DDI16BitWrite(uint32_t ui32Base, uint32_t ui32Reg,
493 uint32_t ui32Mask, uint32_t ui32WrData);
494
495
496 //*****************************************************************************
497 //
498 //! \brief Write a bit field via the DDI using 16-bit maskable write.
499 //!
500 //! Requires that bitfields not space the low/high word boundary.
501 //!
502 //! \note Both the AUX module and the clock for the AUX SMPH module must be
503 //! enabled before calling this function.
504 //!
505 //! \param ui32Base is the base address of the DDI port.
506 //! \param ui32Reg is register to access.
507 //! \param ui32Mask is the mask defining which of the 16 bits that should be
508 //! overwritten. The mask must be defined in the lower half of the 32 bits.
509 //! \param ui32Shift
510 //! \param ui32Data
511 //!
512 //! \return None
513 //
514 //*****************************************************************************
515 extern void DDI16BitfieldWrite(uint32_t ui32Base, uint32_t ui32Reg,
516 uint32_t ui32Mask, uint32_t ui32Shift,
517 uint16_t ui32Data);
518
519 //*****************************************************************************
520 //
521 //! \brief Read a bit via the DDI using 16-bit read.
522 //!
523 //! \note Both the AUX module and the clock for the AUX SMPH module must be
524 //! enabled before calling this function.
525 //!
526 //! \param ui32Base is the base address of the DDI module.
527 //! \param ui32Reg is the register to read.
528 //! \param ui32Mask defines the bit which should be read.
529 //!
530 //! \return Returns a zero if bit selected by mask is '0'. Else returns the mask.
531 //
532 //*****************************************************************************
533 extern uint16_t DDI16BitRead(uint32_t ui32Base, uint32_t ui32Reg,
534 uint32_t ui32Mask);
535
536 //*****************************************************************************
537 //
538 //! \brief Read a bitfield via the DDI using 16-bit read.
539 //!
540 //! Requires that bit fields do not space the low/high word boundary.
541 //!
542 //! \note Both the AUX module and the clock for the AUX SMPH module must be
543 //! enabled before calling this function.
544 //!
545 //! \param ui32Base is the base address of the DDI port.
546 //! \param ui32Reg is register to access.
547 //! \param ui32Mask is the mask defining which of the 16 bits that should be
548 //! overwritten. The mask must be defined in the lower half of the 32 bits.
549 //! \param ui32Shift defines the required shift of the data to align with bit 0.
550 //!
551 //! \return Returns data aligned to bit 0.
552 //
553 //*****************************************************************************
554 extern uint16_t DDI16BitfieldRead(uint32_t ui32Base, uint32_t ui32Reg,
555 uint32_t ui32Mask, uint32_t ui32Shift);
556
557 //*****************************************************************************
558 //
559 // Support for DriverLib in ROM:
560 // Redirect to implementation in ROM when available.
561 //
562 //*****************************************************************************
563 #if !defined(DRIVERLIB_NOROM) && !defined(DOXYGEN)
564 #include <driverlib/rom.h>
565 #ifdef ROM_DDI16BitWrite
566 #undef DDI16BitWrite
567 #define DDI16BitWrite ROM_DDI16BitWrite
568 #endif
569 #ifdef ROM_DDI16BitfieldWrite
570 #undef DDI16BitfieldWrite
571 #define DDI16BitfieldWrite ROM_DDI16BitfieldWrite
572 #endif
573 #ifdef ROM_DDI16BitRead
574 #undef DDI16BitRead
575 #define DDI16BitRead ROM_DDI16BitRead
576 #endif
577 #ifdef ROM_DDI16BitfieldRead
578 #undef DDI16BitfieldRead
579 #define DDI16BitfieldRead ROM_DDI16BitfieldRead
580 #endif
581 #endif
582
583 //*****************************************************************************
584 //
585 // Mark the end of the C bindings section for C++ compilers.
586 //
587 //*****************************************************************************
588 #ifdef __cplusplus
589 }
590 #endif
591
592 #endif // __DDI_H__
593
594 //*****************************************************************************
595 //
596 //! Close the Doxygen group.
597 //! @}
598 //! @}
599 //
600 //*****************************************************************************
601