MotorControlModuleSDFM_TMS3.../Projects/mem_test/device/driverlib/erad.c

550 lines
18 KiB
C

//###########################################################################
//
// FILE: erad.c
//
// TITLE: C28x ERAD driver.
//
//###########################################################################
#include "erad.h"
//*****************************************************************************
//
// ERAD_configBusComp
//
//*****************************************************************************
void
ERAD_configBusComp(uint32_t base, ERAD_BusComp_Config config_params)
{
//
// Check if owner is APPLICATION or NO_OWNER
//
ASSERT((ERAD_getOwnership() == ERAD_OWNER_APPLICATION) ||
(ERAD_getOwnership() == ERAD_OWNER_NOOWNER));
//
// Check if the base is valid
//
ASSERT(ERAD_isValidBusCompBase(base));
//
// Check if the bus comparator is in ERAD_STATE_IDLE
//
ASSERT(ERAD_getBusCompStatus(base) == ERAD_STATE_IDLE);
//
// Write into necessary registers to configure the bus comparator
//
EALLOW;
HWREG(base + ERAD_O_HWBP_MASK) = config_params.mask;
HWREG(base + ERAD_O_HWBP_REF) = config_params.reference;
//
// Set the comparison mode and the CPU bus to be monitored
// Enable interrupt and CPU halt if specified in the parameters
//
HWREGH(base + ERAD_O_HWBP_CNTL) =
((uint16_t)config_params.comp_mode << ERAD_HWBP_CNTL_COMP_MODE_S) |
((uint16_t)config_params.bus_sel << ERAD_HWBP_CNTL_BUS_SEL_S) |
((uint16_t)config_params.enable_stop << ERAD_HWBP_CNTL_STOP_S) |
((uint16_t)config_params.enable_int << ERAD_HWBP_CNTL_RTOSINT_S);
EDIS;
}
//*****************************************************************************
//
// ERAD_configCounterInCountingMode
//
//*****************************************************************************
void
ERAD_configCounterInCountingMode(uint32_t base,
ERAD_Counter_Config config_params)
{
//
// Check if owner is APPLICATION or NO_OWNER
//
ASSERT((ERAD_getOwnership() == ERAD_OWNER_APPLICATION) ||
(ERAD_getOwnership() == ERAD_OWNER_NOOWNER));
//
// Check if the base is valid
//
ASSERT(ERAD_isValidCounterBase(base));
//
// Check if the counter is in ERAD_STATE_IDLE
//
ASSERT(ERAD_getCounterStatus(base) == ERAD_STATE_IDLE);
//
// Write into registers to configure the counter
//
EALLOW;
HWREG(base + ERAD_O_CTM_REF) = config_params.reference;
if(config_params.event == ERAD_EVENT_NO_EVENT)
{
//
// If ERAD_EVENT_NO_EVENT is selected, clear the counter input select
// enable bit. The counter will count CPU cycles.
//
HWREGH(base + ERAD_O_CTM_CNTL) &= ERAD_CTM_CNTL_CNT_INP_SEL_EN;
}
else
{
//
// For any other value, set the event to be counted and counter input
// select enable bit.
//
HWREGH(base + ERAD_O_CTM_INPUT_SEL) =
(((uint16_t)config_params.event << ERAD_CTM_INPUT_SEL_CNT_INP_SEL_S) &
ERAD_CTM_INPUT_SEL_CNT_INP_SEL_M);
HWREGH(base + ERAD_O_CTM_CNTL) |= ERAD_CTM_CNTL_CNT_INP_SEL_EN;
}
//
// Set the counter in Normal count mode
// Set the event mode as Rising edge or Active
// Enable interrupt, CPU halt and reset on match if specified in the
// parameters
//
HWREGH(base + ERAD_O_CTM_CNTL) =
(HWREGH(base + ERAD_O_CTM_CNTL) & (~(ERAD_CTM_CNTL_START_STOP_CUMULATIVE |
ERAD_CTM_CNTL_RTOSINT |
ERAD_CTM_CNTL_STOP |
ERAD_CTM_CNTL_RST_ON_MATCH |
ERAD_CTM_CNTL_EVENT_MODE |
ERAD_CTM_CNTL_START_STOP_MODE))) |
((uint16_t)config_params.enable_int << ERAD_CTM_CNTL_RTOSINT_S) |
((uint16_t)config_params.enable_stop << ERAD_CTM_CNTL_STOP_S) |
((uint16_t)config_params.event_mode << ERAD_CTM_CNTL_EVENT_MODE_S) |
((uint16_t)config_params.rst_on_match << ERAD_CTM_CNTL_RST_ON_MATCH_S);
EDIS;
}
//*****************************************************************************
//
// ERAD_configCounterInStartStopMode
//
//*****************************************************************************
void
ERAD_configCounterInStartStopMode(uint32_t base,
ERAD_Counter_Config config_params,
ERAD_Counter_Input_Event start_event,
ERAD_Counter_Input_Event stop_event)
{
//
// Check if owner is APPLICATION or NO_OWNER
//
ASSERT((ERAD_getOwnership() == ERAD_OWNER_APPLICATION) ||
(ERAD_getOwnership() == ERAD_OWNER_NOOWNER));
//
// Check if the base is valid
//
ASSERT(ERAD_isValidCounterBase(base));
//
// Check if the counter is in IDLE state
//
ASSERT(ERAD_getCounterStatus(base) == ERAD_STATE_IDLE);
//
// Write into registers to configure the counter
//
EALLOW;
HWREG(base + ERAD_O_CTM_REF) = config_params.reference;
if(config_params.event == ERAD_EVENT_NO_EVENT)
{
//
// If ERAD_EVENT_NO_EVENT is selected, clear the counter input select
// enable bit. The counter will count CPU cycles.
// Set start and stop events
//
HWREGH(base + ERAD_O_CTM_CNTL) &= ~ERAD_CTM_CNTL_CNT_INP_SEL_EN;
HWREGH(base + ERAD_O_CTM_INPUT_SEL) =
((uint16_t)start_event << ERAD_CTM_INPUT_SEL_STA_INP_SEL_S);
HWREGH(base + ERAD_O_CTM_INPUT_SEL_2) |=
((uint16_t)stop_event << ERAD_CTM_INPUT_SEL_2_STO_INP_SEL_S);
}
else
{
//
// For any other value, set the counter input select enable bit and
// configure the counter input, start event and stop event,
//
//
HWREGH(base + ERAD_O_CTM_CNTL) |= ERAD_CTM_CNTL_CNT_INP_SEL_EN;
HWREGH(base + ERAD_O_CTM_INPUT_SEL) =
((uint16_t)config_params.event << ERAD_CTM_INPUT_SEL_CNT_INP_SEL_S) |
((uint16_t)start_event << ERAD_CTM_INPUT_SEL_STA_INP_SEL_S);
HWREGH(base + ERAD_O_CTM_INPUT_SEL_2) |=
((uint16_t)stop_event << ERAD_CTM_INPUT_SEL_2_STO_INP_SEL_S);
}
//
// Set the counter in Normal count mode
// Set the event mode as Rising edge or Active
// Enable interrupt, CPU halt and reset on match if specified in the
// parameters
//
HWREGH(base + ERAD_O_CTM_CNTL) =
(HWREGH(base + ERAD_O_CTM_CNTL) & (~(ERAD_CTM_CNTL_START_STOP_CUMULATIVE |
ERAD_CTM_CNTL_RTOSINT |
ERAD_CTM_CNTL_STOP |
ERAD_CTM_CNTL_RST_ON_MATCH |
ERAD_CTM_CNTL_EVENT_MODE))) |
ERAD_CTM_CNTL_START_STOP_MODE |
((uint16_t)config_params.enable_int << ERAD_CTM_CNTL_RTOSINT_S) |
((uint16_t)config_params.enable_stop << ERAD_CTM_CNTL_STOP_S) |
((uint16_t)config_params.event_mode << ERAD_CTM_CNTL_EVENT_MODE_S) |
((uint16_t)config_params.rst_on_match << ERAD_CTM_CNTL_RST_ON_MATCH_S);
EDIS;
}
//*****************************************************************************
//
// ERAD_configCounterInCumulativeMode
//
//*****************************************************************************
void
ERAD_configCounterInCumulativeMode(uint32_t base,
ERAD_Counter_Config config_params,
ERAD_Counter_Input_Event start_event,
ERAD_Counter_Input_Event stop_event)
{
//
// Check if owner is APPLICATION or NO_OWNER
//
ASSERT((ERAD_getOwnership() == ERAD_OWNER_APPLICATION) ||
(ERAD_getOwnership() == ERAD_OWNER_NOOWNER));
//
// Check if the base is valid
//
ASSERT(ERAD_isValidCounterBase(base));
//
// Check if the counter is in IDLE state
//
ASSERT(ERAD_getCounterStatus(base) == ERAD_STATE_IDLE);
//
// Write into registers to configure the counter
//
EALLOW;
HWREG(base + ERAD_O_CTM_REF) = config_params.reference;
if(config_params.event == ERAD_EVENT_NO_EVENT)
{
//
// If ERAD_EVENT_NO_EVENT is selected, clear the counter input select
// enable bit. The counter will count CPU cycles.
// Set start and stop events
//
HWREGH(base + ERAD_O_CTM_CNTL) &= ~ERAD_CTM_CNTL_CNT_INP_SEL_EN;
HWREGH(base + ERAD_O_CTM_INPUT_SEL) =
((uint16_t)start_event << ERAD_CTM_INPUT_SEL_STA_INP_SEL_S);
HWREGH(base + ERAD_O_CTM_INPUT_SEL_2) |=
((uint16_t)stop_event << ERAD_CTM_INPUT_SEL_2_STO_INP_SEL_S);
}
else
{
//
// For any other value, set the counter input select enable bit and
// configure the counter input, start event and stop event,
//
//
HWREGH(base + ERAD_O_CTM_CNTL) |= ERAD_CTM_CNTL_CNT_INP_SEL_EN;
HWREGH(base + ERAD_O_CTM_INPUT_SEL) =
((uint16_t)config_params.event << ERAD_CTM_INPUT_SEL_CNT_INP_SEL_S) |
((uint16_t)start_event << ERAD_CTM_INPUT_SEL_STA_INP_SEL_S);
HWREGH(base + ERAD_O_CTM_INPUT_SEL_2) |=
((uint16_t)stop_event << ERAD_CTM_INPUT_SEL_2_STO_INP_SEL_S);
}
//
// Set the counter in Normal count mode
// Set the event mode as Rising edge or Active
// Enable interrupt, CPU halt and reset on match if specified in the
// parameters
//
HWREGH(base + ERAD_O_CTM_CNTL) =
(HWREGH(base + ERAD_O_CTM_CNTL) & (~(ERAD_CTM_CNTL_RTOSINT |
ERAD_CTM_CNTL_STOP |
ERAD_CTM_CNTL_RST_ON_MATCH |
ERAD_CTM_CNTL_EVENT_MODE))) |
ERAD_CTM_CNTL_START_STOP_MODE |
ERAD_CTM_CNTL_START_STOP_CUMULATIVE |
((uint16_t)config_params.enable_int << ERAD_CTM_CNTL_RTOSINT_S) |
((uint16_t)config_params.enable_stop << ERAD_CTM_CNTL_STOP_S) |
((uint16_t)config_params.event_mode << ERAD_CTM_CNTL_EVENT_MODE_S) |
((uint16_t)config_params.rst_on_match << ERAD_CTM_CNTL_RST_ON_MATCH_S);
EDIS;
}
//*****************************************************************************
//
// ERAD_configMask
//
//*****************************************************************************
void
ERAD_configMask(ERAD_Mask mask, uint32_t instances, bool enable_int)
{
uint16_t bitpos;
uint16_t mask_tmp = (uint16_t)mask;
EALLOW;
if(mask_tmp < 4U)
{
bitpos = mask_tmp << 3U;
HWREG(ERAD_GLOBAL_BASE + ERAD_O_GLBL_EVENT_AND_MASK) =
(HWREG(ERAD_GLOBAL_BASE + ERAD_O_GLBL_EVENT_AND_MASK) |
(0xFFUL << bitpos)) & (~(instances << bitpos));
bitpos = mask_tmp;
if(enable_int)
{
HWREGH(ERAD_GLOBAL_BASE + ERAD_O_GLBL_AND_EVENT_INT_MASK) &=
~(1U << bitpos);
}
else
{
HWREGH(ERAD_GLOBAL_BASE + ERAD_O_GLBL_AND_EVENT_INT_MASK) |=
(1U << bitpos);
}
}
else
{
bitpos = (mask_tmp - 4U) << 3U;
HWREG(ERAD_GLOBAL_BASE + ERAD_O_GLBL_EVENT_OR_MASK) =
(HWREG(ERAD_GLOBAL_BASE + ERAD_O_GLBL_EVENT_OR_MASK) |
(0xFFUL << bitpos)) & (~(instances << bitpos));
bitpos = mask_tmp - 4U;
if(enable_int)
{
HWREGH(ERAD_GLOBAL_BASE + ERAD_O_GLBL_OR_EVENT_INT_MASK) &=
~(1U << bitpos);
}
else
{
HWREGH(ERAD_GLOBAL_BASE + ERAD_O_GLBL_OR_EVENT_INT_MASK) |=
(1U << bitpos);
}
}
EDIS;
}
//*****************************************************************************
//
// ERAD_profile
//
//*****************************************************************************
void
ERAD_profile(ERAD_Profile_Params config_params)
{
ERAD_BusComp_Config buscomp1_params, buscomp2_params;
ERAD_Counter_Config counter_params;
//
// Clear any previous events
//
ERAD_clearBusCompEvent(config_params.busComp_base1);
ERAD_clearBusCompEvent(config_params.busComp_base2);
//
// Clear any previous events and overflow
//
ERAD_clearCounterEvent(config_params.counter_base);
ERAD_clearCounterOverflow(config_params.counter_base);
//
// Reset the counter
//
ERAD_resetCounter(ERAD_getCounterInstance(config_params.counter_base));
//
// Configure the first bus comparator
// No interrupt or CPU halt. Compare for equality. No mask.
// Reference is the address of the first instruction
//
buscomp1_params.bus_sel = config_params.bus_sel;
buscomp1_params.comp_mode = ERAD_BUSCOMP_COMPMODE_EQ;
buscomp1_params.enable_stop = 0;
buscomp1_params.enable_int = 0;
buscomp1_params.mask = 0x0;
buscomp1_params.reference = config_params.start_address;
ERAD_configBusComp(config_params.busComp_base1, buscomp1_params);
//
// Configure the second bus comparator
// No interrupt or CPU halt. Compare for equality. No mask.
// Reference is the address of the last instruction
//
buscomp2_params.bus_sel = config_params.bus_sel;
buscomp2_params.comp_mode = ERAD_BUSCOMP_COMPMODE_EQ;
buscomp2_params.enable_stop = 0;
buscomp2_params.enable_int = 0;
buscomp2_params.mask = 0x0;
buscomp2_params.reference = config_params.end_address;
ERAD_configBusComp(config_params.busComp_base2, buscomp2_params);
//
// Configure the counter
// No interrupt, no CPU halt, no reset on match, no reference.
// Counting the number of CPU cycles
// Start event is the first bus comparator and stop is the second
//
counter_params.enable_int = 0;
counter_params.enable_stop = 0;
counter_params.rst_on_match = 0;
counter_params.reference = 0x0;
counter_params.event_mode = ERAD_COUNTER_MODE_ACTIVE;
counter_params.event = ERAD_EVENT_NO_EVENT;
ERAD_Counter_Input_Event start = (ERAD_Counter_Input_Event)
(ERAD_BUSCOMP_BASE_TO_EVENT(config_params.busComp_base1));
ERAD_Counter_Input_Event stop = (ERAD_Counter_Input_Event)
(ERAD_BUSCOMP_BASE_TO_EVENT(config_params.busComp_base2));
ERAD_configCounterInStartStopMode(config_params.counter_base,
counter_params, start, stop);
//
// Enable the modules
//
ERAD_enableModules(ERAD_getBusCompInstance(config_params.busComp_base1) |
ERAD_getBusCompInstance(config_params.busComp_base2) |
ERAD_getCounterInstance(config_params.counter_base));
}
//*****************************************************************************
//
// ERAD_enableInterruptAtAddress
//
//*****************************************************************************
void
ERAD_enableInterruptOnAddressHit(ERAD_AddressHit_Params config_params,
uint32_t busComp_base)
{
ERAD_BusComp_Config buscomp_params;
//
// Clear any previous events
//
ERAD_clearBusCompEvent(busComp_base);
//
// Set the address and mask. Disable CPU halt
// and enable Interrupt
//
buscomp_params.reference = config_params.address;
buscomp_params.mask = config_params.mask;
buscomp_params.enable_stop = 0;
buscomp_params.enable_int = 1;
//
// Comparison mode is set to equality and the bus to be
// monitored is the Virtual Program Counter
//
buscomp_params.comp_mode = ERAD_BUSCOMP_COMPMODE_EQ;
buscomp_params.bus_sel = config_params.bus_sel;
//
// Configure the bus comparator
//
ERAD_configBusComp(busComp_base, buscomp_params);
//
// Enable the bus comparator
//
ERAD_enableModules(ERAD_getBusCompInstance(busComp_base));
}
//*****************************************************************************
//
// ERAD_countEventHits
//
//*****************************************************************************
void
ERAD_countAddressHits(ERAD_AddressHit_Params config_params,
uint32_t busComp_base, uint32_t counter_base)
{
ERAD_BusComp_Config buscomp_params;
ERAD_Counter_Config counter_params;
//
// Clear any previous events and overflows
//
ERAD_clearBusCompEvent(busComp_base);
ERAD_clearCounterEvent(counter_base);
ERAD_clearCounterOverflow(counter_base);
//
// Reset the counter
//
ERAD_resetCounter(ERAD_getCounterInstance(counter_base));
//
// Configure the bus comparator
// No interrupt or CPU halt. Compare for equality. No mask.
// Reference is the address of the instruction to be counted
// Bus to be monitored is specified in the bus argument
//
buscomp_params.reference = config_params.address;
buscomp_params.mask = config_params.mask;
buscomp_params.comp_mode = ERAD_BUSCOMP_COMPMODE_EQ;
buscomp_params.enable_stop = 0;
buscomp_params.bus_sel = config_params.bus_sel;
buscomp_params.enable_int = 0;
ERAD_configBusComp(busComp_base, buscomp_params);
//
// Configure the counter
// No interrupt, no CPU halt, no reset on match, no reference.
// Counting the number of rising edges of the bus comparator event
//
counter_params.enable_int = 0;
counter_params.enable_stop = 0;
counter_params.event_mode = ERAD_COUNTER_MODE_RISING_EDGE;
counter_params.rst_on_match = 0;
counter_params.reference = 0x0;
counter_params.event = (ERAD_Counter_Input_Event)
(ERAD_BUSCOMP_BASE_TO_EVENT(busComp_base));
ERAD_configCounterInCountingMode(counter_base, counter_params);
//
// Enable the modules
//
ERAD_enableModules(ERAD_getBusCompInstance(busComp_base) |
ERAD_getCounterInstance(counter_base));
}
//
// End of file
//