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

Dwt.h

Committer:
YasuhiroKawai
Date:
2017-10-08
Revision:
0:37014c6bb5cd

File content as of revision 0:37014c6bb5cd:

/**
 * 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 */