This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

DMTimer-Example speedup

Genius 5820 points


Hi,

after there have been nameable troubles in using the DMTimerCounter-example for higher frequencies I modified the code a bit to get an DMTimer-caused interrupt every 0,5 usec. Thus I changed the following things comparing to original code (please refer to full sources below):

  • enabled cache
  • programmed MMU
  • used an additional GPIO for output that is toggeled on every call of the DMTimerIsr so that the frequency can be checked using an oscilloscope
  • added calls DMTimerPreScalerClkDisable(), DMTimerReset() and DMTimerPostedModeConfig()
  • endless main loop and toggling LED in ISR in order to see the thingy is working

Now calling the DMTimerIsr every 0,5 usec seems to be the limit, it is not possible to have bigger timer initial/reload values in order to get higher frequencies, these values seem to be ignored.

Theoretically there should be enough computing power available on a BeagleBone Black so that calling the DMTimerIsr more often should be possible.

So: how can I speedup the whole thing and have higher frequencies with the DMTimer?

Thanks!

PS: for your reference, this is the full code where a ISR-frequency of max 2 MHz is possible:

#include "soc_AM335x.h"
#include "beaglebone.h"
#include "interrupt.h"
#include "dmtimer.h"
#include "error.h"
#include "gpio_v2.h"
#include "cache.h"
#include "mmu.h"

#define GPIO_INSTANCE_ADDRESS           (SOC_GPIO_1_REGS)
#define GPIO_INSTANCE_PIN_NUMBER        (23)

#define TIMER_INITIAL_COUNT             (0xFFFFFFFFu-12)
#define TIMER_RLD_COUNT                 (0xFFFFFFFFu-12)

static void DMTimerAintcConfigure(void);
static void DMTimerSetUp(void);
static void DMTimerIsr(void);

static volatile unsigned int cntValue = 10;
static volatile unsigned int flagIsr = 0;

int cnt=0;

#include "hw_control_AM335x.h"
#include "soc_AM335x.h"
#include "hw_cm_wkup.h"
#include "beaglebone.h"
#include "hw_cm_per.h"
#include "hw_types.h"

#define START_ADDR_DDR                     (0x80000000)
#define START_ADDR_DEV                     (0x44000000)
#define START_ADDR_OCMC                    (0x40300000)
#define NUM_SECTIONS_DDR                   (512)
#define NUM_SECTIONS_DEV                   (960)
#define NUM_SECTIONS_OCMC                  (1)

#ifdef __TMS470__
#pragma DATA_ALIGN(pageTable, 16384);
static volatile unsigned int pageTable[4*1024];
#elif defined(__IAR_SYSTEMS_ICC__)
#pragma data_alignment=16384
static volatile unsigned int pageTable[4*1024];
#else
static volatile unsigned int pageTable[4*1024] __attribute__((aligned(16*1024)));
#endif

void MMUConfigAndEnable(void)
{
    REGION regionDdr = {
                        MMU_PGTYPE_SECTION, START_ADDR_DDR, NUM_SECTIONS_DDR,
                        MMU_MEMTYPE_NORMAL_NON_SHAREABLE(MMU_CACHE_WT_NOWA,
                                                         MMU_CACHE_WB_WA),
                        MMU_REGION_NON_SECURE, MMU_AP_PRV_RW_USR_RW,
                        (unsigned int*)pageTable
                       };
    REGION regionOcmc = {
                         MMU_PGTYPE_SECTION, START_ADDR_OCMC, NUM_SECTIONS_OCMC,
                         MMU_MEMTYPE_NORMAL_NON_SHAREABLE(MMU_CACHE_WT_NOWA,
                                                          MMU_CACHE_WB_WA),
                         MMU_REGION_NON_SECURE, MMU_AP_PRV_RW_USR_RW,
                         (unsigned int*)pageTable
                        };
    REGION regionDev = {
                        MMU_PGTYPE_SECTION, START_ADDR_DEV, NUM_SECTIONS_DEV,
                        MMU_MEMTYPE_DEVICE_SHAREABLE,
                        MMU_REGION_NON_SECURE,
                        MMU_AP_PRV_RW_USR_RW  | MMU_SECTION_EXEC_NEVER,
                        (unsigned int*)pageTable
                       };

    MMUInit((unsigned int*)pageTable);
    MMUMemRegionMap(&regionDdr);
    MMUMemRegionMap(&regionOcmc);
    MMUMemRegionMap(&regionDev);
    MMUEnable((unsigned int*)pageTable);
}

int main(void)
{
   MMUConfigAndEnable();
   CacheEnable(CACHE_ALL);

   GPIO0ModuleClkConfig();
   GPIO1ModuleClkConfig();

   GPIO1Pin23PinMuxSetup();
   HWREG(SOC_CONTROL_REGS + CONTROL_CONF_GPMC_AD(9)) = CONTROL_CONF_MUXMODE(7);

   GPIOModuleEnable(SOC_GPIO_0_REGS);
   GPIOModuleEnable(SOC_GPIO_1_REGS);

   GPIOModuleReset(SOC_GPIO_0_REGS);
   GPIOModuleReset(SOC_GPIO_1_REGS);

   GPIODirModeSet(SOC_GPIO_0_REGS,GPIO_INSTANCE_PIN_NUMBER,GPIO_DIR_OUTPUT);
   GPIODirModeSet(SOC_GPIO_1_REGS,GPIO_INSTANCE_PIN_NUMBER,GPIO_DIR_OUTPUT);

   DMTimer2ModuleClkConfig();
   IntMasterIRQEnable();
   DMTimerAintcConfigure();
   DMTimerSetUp();
   DMTimerIntEnable(SOC_DMTIMER_2_REGS, DMTIMER_INT_OVF_EN_FLAG);
   DMTimerEnable(SOC_DMTIMER_2_REGS);  
   while(1);
}

static void DMTimerAintcConfigure(void)
{
    IntAINTCInit();
    IntRegister(SYS_INT_TINT2, DMTimerIsr);
    IntPrioritySet(SYS_INT_TINT2, 0, AINTC_HOSTINT_ROUTE_IRQ);
    IntSystemEnable(SYS_INT_TINT2);
}

static void DMTimerSetUp(void)
{
	DMTimerPreScalerClkDisable(SOC_DMTIMER_2_REGS);
    DMTimerReset(SOC_DMTIMER_2_REGS);
    DMTimerCounterSet(SOC_DMTIMER_2_REGS, TIMER_INITIAL_COUNT);
    DMTimerReloadSet(SOC_DMTIMER_2_REGS, TIMER_RLD_COUNT);
    DMTimerModeConfigure(SOC_DMTIMER_2_REGS, DMTIMER_AUTORLD_NOCMP_ENABLE);
    DMTimerPostedModeConfig(SOC_DMTIMER_2_REGS,DMTIMER_POSTED);
}

static void DMTimerIsr(void)
{
    DMTimerIntStatusClear(SOC_DMTIMER_2_REGS, DMTIMER_INT_OVF_IT_FLAG);

    if (cnt % 2==0) GPIOPinWrite(SOC_GPIO_0_REGS,GPIO_INSTANCE_PIN_NUMBER,GPIO_PIN_HIGH);
    else GPIOPinWrite(SOC_GPIO_0_REGS,GPIO_INSTANCE_PIN_NUMBER,GPIO_PIN_LOW);

    if (cnt==0) GPIOPinWrite(SOC_GPIO_1_REGS,GPIO_INSTANCE_PIN_NUMBER,GPIO_PIN_HIGH);
    else if (cnt==200000) GPIOPinWrite(SOC_GPIO_1_REGS,GPIO_INSTANCE_PIN_NUMBER,GPIO_PIN_LOW);
    else if (cnt==400000) cnt=-1;
    cnt++;
}