Data Watch-point and Trace unit(DWT) interface.

Revision:
0:37014c6bb5cd
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Dwt.h	Sun Oct 08 05:51:12 2017 +0000
@@ -0,0 +1,177 @@
+/**
+ * DWT class
+ */
+#ifndef DWT_H
+#define DWT_H
+
+/**
+ * The Data Watchpoint and Trace unit intarface
+ *
+ * @code
+ * #include "mbed.h"
+ * #include "Dwt.h"
+ * 
+ * Serial pc(SERIAL_TX, SERIAL_RX);
+ * Dwt dwt;
+ * 
+ * int main() {
+ *     uint32_t t;
+ *     uint32_t n;
+ *
+ *     dwt.enableCYCCNT();
+ *     dwt.resetCYCCNT();
+ *     dwt.startCount();
+ *     <Write some codes to measure the execution cycle here.>
+ *     dwt.stopCount();
+ *     t = dwt.getCYCCNT();
+ *     n = dwt.getInstructionCount();
+ *     pc.printf("%d cycles, %d instructions.\n", t, n);
+ * }
+ * @endcode
+ */
+#define DWT_MAJOR_VERSION   (0)
+#define DWT_MINOR_VERSION   (1)
+
+class Dwt 
+{
+    /**
+     * The Data Watchpoint and Trace unit intarface
+     */
+public:
+
+    /** 
+     * Create a DWT interface
+     */
+    Dwt();
+    
+     /// Returns whether the implementation supports trace sampling and exception tracing.
+     /// true  : Trace sampling and exception tracing supported.
+     /// false : Trace sampling and exception tracing not supported.
+    bool isTRCPKT_Available();
+    /// Returns whether the implementation includes external match signals, CMPMATCH[N].
+    bool isEXTTRIG_Available();
+    /// Returns whether the implementation supports a cycle counter.
+    bool isCYCCNT_Available();
+    /// Returns whether the implementation supports the profiling counters.
+    bool isPRFCNT_Available();
+    
+    void enableCYCCNT();
+    void disableCYCCNT();
+    inline void startCYCCNT() {
+        _regs->DWT_CTRL |= CYCCNTENA;
+    }
+    inline void stopCYCCNT() {
+        _regs->DWT_CTRL &= ~CYCCNTENA;
+    }
+    inline void resetCYCCNT() {
+        _regs->DWT_CYCCNT = 0;
+    }
+    inline uint32_t getCYCCNT() {
+        return(_regs->DWT_CYCCNT);
+    }
+    inline uint32_t readDwtCtrl() {
+        return(_regs->DWT_CTRL);
+    }
+    inline uint32_t getNumComp() {
+        return((_regs->DWT_CTRL & NUMCOMP_MASK) >> NUMCOMP_POS);
+    }
+    void setEvent(uint32_t ev);
+    inline uint32_t getEvent() {
+        return(_regs->DWT_CTRL & EVENA_MASK);
+    }
+    /// Returns additional cycles required to execute multicycle instructions and 
+    /// instruction fetch stalls.
+    inline uint32_t getCPICNT() {
+        return(_regs->DWT_CPICNT);
+    }
+    /// Returns the total cycles spent in exception processing.
+    inline uint32_t getEXCCNT() {
+        return(_regs->DWT_EXCCNT);
+    }
+    /// Returns the total number of cycles that the processor is sleeping.
+    inline uint32_t getSLEEPCNT() {
+        return(_regs->DWT_SLEEPCNT);
+    }
+    /// Returns the additional cycles required to execute all load or 
+    /// store instructions.
+    inline uint32_t getLSUCNT() {
+        return(_regs->DWT_LSUCNT);
+    }
+    /// Returns the number of instructions that takes 0 cycles.
+    inline uint32_t getFOLDCNT() {
+        return(_regs->DWT_FOLDCNT);
+    }
+    /// start all counters
+    inline void startCount() {
+        _regs->DWT_CTRL |= (Dwt::CPIEVTENA | Dwt::EXCEVTENA | Dwt::SLEEPEVTENA | 
+                            Dwt::LSUEVTENA | Dwt::FOLDEVTENA | Dwt::CYCCNTENA);
+    }
+    ///  stop all counters
+    inline void stopCount() {
+        _regs->DWT_CTRL &= ~(Dwt::CPIEVTENA | Dwt::EXCEVTENA | Dwt::SLEEPEVTENA | 
+                             Dwt::LSUEVTENA | Dwt::FOLDEVTENA | Dwt::CYCCNTENA);
+    }
+    /// Returns number of executed instructions.
+    uint32_t getInstructionCount();
+private:
+    typedef struct {
+        uint32_t DWT_COMP;      ///< Provides a reference value for use by 
+                                ///< comparator n.
+        uint32_t DWT_MASK;      ///< Provides the size of the ignore mask applied
+                                ///< to the access address for address range
+                                ///< matching by comparator n.
+        uint32_t DWT_FUNCTION;  ///< Controls the operation of comparator n.
+        uint32_t reserved;
+    } dwt_cmp_regs_t;
+
+    typedef struct {
+        uint32_t DWT_CTRL;      ///< Control register
+        uint32_t DWT_CYCCNT;    ///< Shows or sets the value of the processor 
+                                ///< cycle counter, CYCCNT.
+        uint32_t DWT_CPICNT;    ///< Counts additional cycles required to execute 
+                                ///< multicycle instructions and instruction 
+                                ///< fetch stalls.
+        uint32_t DWT_EXCCNT;    ///< Counts the total cycles spent in exception 
+                                ///< processing.
+        uint32_t DWT_SLEEPCNT;  ///< Counts the total number of cycles that the 
+                                ///< processor is sleeping.
+        uint32_t DWT_LSUCNT;    ///< Increments on the additional cycles required
+                                ///< to execute all load or store instructions.
+        uint32_t DWT_FOLDCNT;   ///< Increments on each instruction that takes 0 
+                                ///< cycles.
+        uint32_t DWT_PCSR;      ///< Samples the current value of the program 
+                                ///< counter.
+        dwt_cmp_regs_t regs[16];
+    } dwt_regs_t;
+    
+    static const uint32_t DWT_REGS_ADDR;
+    static const uint32_t SCB_DEMCR_ADDR;
+
+    static const uint32_t NUMCOMP_POS;
+    static const uint32_t NUMCOMP_MASK;
+    static const uint32_t NOTRCPKT;
+    static const uint32_t NOEXTTRIG;
+    static const uint32_t NOCYCCNT;
+    static const uint32_t NOPRFCNT;
+public:
+    static const uint32_t CYCEVTENA;    /// Enables POSTCNT underflow Event counter packets generation.
+    static const uint32_t FOLDEVTENA;   /// Enables generation of the Folded-instruction counter overflow event. 
+    static const uint32_t LSUEVTENA;    /// Enables generation of the LSU counter overflow event.
+    static const uint32_t SLEEPEVTENA;  /// Enables generation of the Sleep counter overflow event.
+    static const uint32_t EXCEVTENA;    /// Enables generation of the Exception overhead counter overflow event:
+    static const uint32_t CPIEVTENA;    /// Enables generation of the CPI counter overflow event.
+    static const uint32_t EXCTRCENA;    /// Enables generation of the CPI counter overflow event.
+    static const uint32_t PCSAMPLENA;   /// Enables use of POSTCNT counter as a timer for Periodic PC sample packet generation.
+    static const uint32_t CYCCNTENA;    /// Enables CYCCNT.
+
+private:
+    static const uint32_t TRCENA;
+    static const uint32_t EVENA_MASK;
+
+private:    
+    volatile dwt_regs_t *_regs;
+    volatile uint32_t *_scb_demcr_regs;
+};
+
+
+#endif /* DWT_H */