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

Dwt.cpp

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

File content as of revision 0:37014c6bb5cd:


#include <mbed.h>
#include "Dwt.h"

const uint32_t Dwt::DWT_REGS_ADDR = 0xe0001000;
const uint32_t Dwt::SCB_DEMCR_ADDR = 0xe000edfc;

const uint32_t Dwt::NUMCOMP_POS = 28;
const uint32_t Dwt::NUMCOMP_MASK = (0xfU << Dwt::NUMCOMP_POS);
const uint32_t Dwt::NOTRCPKT  = (1 << 27);
const uint32_t Dwt::NOEXTTRIG = (1 << 26);
const uint32_t Dwt::NOCYCCNT  = (1 << 25);
const uint32_t Dwt::NOPRFCNT  = (1 << 24);

const uint32_t Dwt::CYCEVTENA   = (1 << 22);
const uint32_t Dwt::FOLDEVTENA  = (1 << 21);
const uint32_t Dwt::LSUEVTENA   = (1 << 20);
const uint32_t Dwt::SLEEPEVTENA = (1 << 19);
const uint32_t Dwt::EXCEVTENA   = (1 << 18);
const uint32_t Dwt::CPIEVTENA   = (1 << 17);
const uint32_t Dwt::EXCTRCENA   = (1 << 16);
const uint32_t Dwt::PCSAMPLENA  = (1 << 12);
const uint32_t Dwt::CYCCNTENA   = (1 <<  0);

const uint32_t Dwt::TRCENA      = (1 << 24);

const uint32_t Dwt::EVENA_MASK = Dwt::CYCEVTENA | Dwt::FOLDEVTENA | Dwt::LSUEVTENA | Dwt::SLEEPEVTENA |
                                 Dwt::EXCEVTENA | Dwt::CPIEVTENA  | Dwt::EXCTRCENA | Dwt::PCSAMPLENA |
                                 Dwt::CYCCNTENA;



Dwt::Dwt()
{
    _regs = (volatile dwt_regs_t *)DWT_REGS_ADDR;
    _scb_demcr_regs = (volatile uint32_t *)SCB_DEMCR_ADDR;
}

bool
Dwt::isTRCPKT_Available()
{
    return((_regs->DWT_CTRL & NOTRCPKT) == 0);    
}


bool
Dwt::isEXTTRIG_Available()
{
    return((_regs->DWT_CTRL & NOEXTTRIG) == 0);    
}

bool
Dwt::isCYCCNT_Available()
{
    return((_regs->DWT_CTRL & NOCYCCNT) == 0);    
}

bool
Dwt::isPRFCNT_Available()
{
    return((_regs->DWT_CTRL & NOPRFCNT) == 0);    
}

void
Dwt::enableCYCCNT()
{
    *_scb_demcr_regs |= TRCENA;
}

void
Dwt::disableCYCCNT()
{
    *_scb_demcr_regs &= ~TRCENA;
}

void
Dwt::setEvent(uint32_t ev)
{
    uint32_t tmp;
    tmp = _regs->DWT_CTRL;
    tmp &= ~EVENA_MASK;
    tmp |= ev & EVENA_MASK;
    _regs->DWT_CTRL = tmp;
}

/// ICNT = CNT_CYCLES + CNT_FOLD - (CNT_LSU + CNT_EXC + CNT_SLEEP + CNT_CPI)
uint32_t
Dwt::getInstructionCount()
{
    uint32_t cnt_cycles = getCYCCNT();
    uint32_t cnt_fold   = getFOLDCNT();
    uint32_t cnt_lsu    = getLSUCNT();
    uint32_t cnt_exc    = getEXCCNT();
    uint32_t cnt_sleep  = getSLEEPCNT();
    uint32_t cnt_cpi    = getCPICNT();
    return(cnt_cycles + cnt_fold - (cnt_lsu + cnt_exc + cnt_sleep + cnt_cpi));
}