⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dbgm.c

📁 使用在ti dm64xx 系列的realtime system
💻 C
字号:
/******************************************************************************
* FILENAME: DBGM.C
*
* DBGM tutorial code 
* 
* This file should be used in conjunction with the dbgm.pjt project 
*
* It consists of a loop which performs an FIR filter and three interrupt
* service routines (ISRs). Of the three ISRs, one is not time-critical
* (ISR3) and can be held off indefinitely. Another, ISR1, is extremely
* time-critical and must be serviced, even while in another ISR. ISR2
* is time-critical, but will not preempt ISR1.
*
*     Code              Priority        Background/foreground  Interruptible?
*     ---------         --------------  ---------------------  --------------
*     main loop         lowest          background             Yes
*     ISR3              second lowest   background             Yes
*     ISR2              second highest  foreground             Yes
*     ISR1              highest         foreground             No
* 
******************************************************************************/

/*------------------------------------------------------------------------------*/
/* CSL/RTS includes                                                             */
/*------------------------------------------------------------------------------*/

#include <csl.h>
#include <csl_irq.h>
#include <csl_timer.h> 
#include "dbgm.h"
#include "c6x.h"

unsigned int timer0value=0;
unsigned int timer1value=0;
unsigned int timer2value=0;

void SetupInterrupts(void);
void ConfigureAllTimers(void);
void SelectTimeCriticalInterrupts(void);

/*----------------------------------------------------------------------------
* Global variables which monitor interrupt service routine (ISR) activity.
*----------------------------------------------------------------------------*/
typedef enum { NoIsrActive, Isr1Active, Isr2Active, Isr3Active} ISR_LIST;
static volatile ISR_LIST WhatIsrActive = NoIsrActive;

static volatile uint32 Isr0 = 0;
static volatile uint32 Isr1 = 0;
static volatile uint32 Isr2 = 0;

/*-----------------------------------------------------------------------------
* Global variables used by main loop
*----------------------------------------------------------------------------*/
#define FIR_TAPS            16
const int16 AvgFirCoeff[FIR_TAPS] =
{
    2048,   2048,   2048,   2048,
    2048,   2048,   2048,   2048,
    2048,   2048,   2048,   2048,
    2048,   2048,   2048,   2048,    
};

void intConfig(void);
                     
/*--------------------------------------------------------------------------*/
/* Initialize CSL and open the next available DMA channel for data transfer */
/*--------------------------------------------------------------------------*/ 
int main(void)
{
    volatile int KeepRunning = 1;
    static int16 x[FIR_TAPS];
    int i;            
    
    CSL_init(); 
    ConfigureAllTimers();
    
    for (i = 0; i < FIR_TAPS; i++)
        x[i] = 0;
        
    /*---- Setting up interrupts is processor-specific ------------------*/
    SelectTimeCriticalInterrupts();
 
    SetupInterrupts();
    
    /*---- When we're not taking interrupts, perform an FIR -----------------*/
    while ( KeepRunning )       /* Run until the user sets KeepRunning to 0  */
    {
        int16 Result;
        
        x[0] = InputData();
        Result = Fir32(x, AvgFirCoeff) >> 15;
        
        OutputData(Result);
    }
    return 0;
}

/*-----------------------------------------------------------------------------
* int16 InputData(void)
*
* Pretend to input data from some external source like an A/D, but actually
* just generate it randomly. Note that this function is not re-enterant.
*----------------------------------------------------------------------------*/
int16 InputData(void)
{
    static int16 Seed = 21845;
    
    return ( PseudoRand16(&Seed) );
}

/*-----------------------------------------------------------------------------
* void OutputData(int16 Data)
*
* Pretend to output data to some external source like a D/A, but actually
* just write it to an on-chip memory location.
*----------------------------------------------------------------------------*/
static int16 OutputDataMem;
volatile int16 * OutputDataPtr = &OutputDataMem;
void OutputData(int16 Data)
{
    *OutputDataPtr = Data;
}

/*-----------------------------------------------------------------------------
* int32 Fir32(int16 x[], int16 coeff[])
*
* Calculate the Finite Impulse Response (FIR)
* The GUARD_BITS should be integer(ln(TAPS)/ln(2))
*----------------------------------------------------------------------------*/
const int GUARD_BITS = 4;
int32 Fir32(int16 x[], const int16 coeff[])
{
    int32 sum;
    int i;
    int32 mfreg0_value;

    i = FIR_TAPS - 1;
    sum = ( (int32)x[i] * (int32)coeff[i] ) >> GUARD_BITS;
    
    /*-------------------------------------------------------*/
    /* Turn DBGM ON by writing a '1' in the appropriate bit  */
    /* location in the MF_REG0 register                      */
    /*-------------------------------------------------------*/
    mfreg0_value = 0;
    mfreg0_value = MF0_DBGM_LD;
    mfreg0_value |= MF0_DBGM;
    *MF_REG0_ADDR = mfreg0_value;
    
    /*-------------------------------------------------------*/
    /* For the tutorial lesson on DBGM usage:                */
    /* Consider the following code section in the for loop   */
    /* as a example for a time critical section.  Let us     */
    /* further say that this code section must not be        */
    /* disturbed by ongoing emulation accesses.  These       */
    /* accesses may occur for purposes of memory and register*/
    /* window refreshes or RTDX transactions                 */
    /*-------------------------------------------------------*/
    /* EXAMPLE OF TIME CRITICAL CODE SECTION                 */
    
    for (i-- ; i >= 0; i--)
    {
        sum += ( (int32)x[i] * (int32)coeff[i] ) >> GUARD_BITS;
        x[i+1] = x[i];
    }
    
    /* END OF TIME CRITICAL CODE SECTION                     */ 
    /*-------------------------------------------------------*/
    /* Clear the DBGM bit by writing a '0' in the appropriate*/
    /* bit location in the MF_REG0 register                  */
    /*-------------------------------------------------------*/      
    
    mfreg0_value = 0;
    mfreg0_value = MF0_DBGM_LD;
    mfreg0_value &= ~MF0_DBGM;
    *MF_REG0_ADDR = mfreg0_value;
    
    return ( sum );
}

/*-----------------------------------------------------------------------------
* int16 PseudoRand(void)
*
* Use a linear congruential psuedo random generator, which is very fast.
* The basic calculation is:
* Rndnum(n) = (  (Rndnum(n-1) * MULT) + INC  ) modulo M
*  MULT is determined by number theory that I don't pretend to understand,
*  but supposedly the last 3 digits (in decimal) 821, 621, 421, or 221.
*  INC is a prime number.
*  A good initial seed value (i.e. Rndnum(0) is 21845, which is just 65535
*  divided by 3.
*----------------------------------------------------------------------------*/
const int16 Mult = 31821;
const int16 Inc = 13849;
int16 PseudoRand16(int16 * Seed)
{
    *Seed = (  (int32)*Seed * Mult + Inc ) & 0xFFFF;
    return (*Seed);
}


/*-----------------------------------------------------------------------------
* Indicate that Isr1 is being performed, and increment the number of times
* it has been performed. Every so often, take a longer time than normal
* to introduce some variability into the system timing.
*
* This is Timer0.  An interrupt via timer0 is generated by enabling Bit14 of
* the IER (Interrupt Enable Register)
*----------------------------------------------------------------------------*/

interrupt void
PerformIsr1(void)
{
    WhatIsrActive = Isr1Active;
    Isr0++;
    if ((Isr0 % 8) == 0)
        TakeALongTime();
    WhatIsrActive = NoIsrActive;
    timer0value++;
}

/*-----------------------------------------------------------------------------
* Indicate that Isr2 is being performed, and increment the number of times
* it has been performed. Every so often, take a longer time than normal
* to introduce some variability into the system timing.
*
* This is Timer1.  An interrupt via timer1 is generated by enabling Bit15 of
* the IER (Interrupt Enable Register).  This is the default allocation for 
* the timer 1 interrupt.
*----------------------------------------------------------------------------*/

interrupt void
PerformIsr2(void)
{
    WhatIsrActive = Isr2Active;
    Isr1++;
    if ((Isr1 % 8) == 0)
        TakeALongTime();
    WhatIsrActive = NoIsrActive;
    timer1value++;
}

/*-----------------------------------------------------------------------------
* Indicate that Isr3 is being performed, and increment the number of times
* it has been performed. Every so often, take a longer time than normal
* to introduce some variability into the system timing.
*
* This is Timer2.  An interrupt via timer2 is generated by enabling Bit13 of
* the IER (Interrupt Enable Register).  There is no default allocation for 
* the Timer2 interrupt. It is simply assigned to interrupt 13 in this 
* application.
*----------------------------------------------------------------------------*/

interrupt void
PerformIsr3(void)
{
    WhatIsrActive = Isr3Active;
    Isr2++;
    if ((Isr2 % 8) == 0)
        TakeALongTime();
    WhatIsrActive = NoIsrActive;
    timer2value++;
}

/*-----------------------------------------------------------------------------
* void TakeALongTime(void)
*
* This function does nothing useful - it just wastes time.
*----------------------------------------------------------------------------*/
void TakeALongTime(void)
{
    volatile uint16 Output;
    uint16 i;
    
    for (i = 0; i < 0x1; i++)
         Output = i;
}

/* ----------------------------------------------------------------------*/
/*           Copyright (C) 2001 Texas Instruments Incorporated.          */
/*                           All Rights Reserved                         */
/*-----------------------------------------------------------------------*/

void SetupInterrupts(void)
{
    IRQ_resetAll();                       /* Reset all maskable interrupts  */
  	IRQ_enable(IRQ_EVT_TINT0);            /* Enable timer0 -> CPU interrupt */
    IRQ_enable(IRQ_EVT_TINT1);            /* Enable timer1 -> CPU interrupt */
    IRQ_map(IRQ_EVT_TINT2,13);            /* Enable timer2 -> CPU interrupt */
    IRQ_enable(IRQ_EVT_TINT2);            /* Enable timer1 -> CPU interrupt */
    IRQ_nmiEnable();                      /* Enable non-maskable interrupt  */
    IRQ_globalEnable();                   /* Globally enable all interrupts */
} /* end SetupInterrupts() */

void ConfigureAllTimers(void)
{
    TIMER_Handle timer0;
    TIMER_Handle timer1;
    TIMER_Handle timer2;
    
    timer0 = TIMER_open(TIMER_DEV0,0);
    TIMER_configArgs( timer0, 0x000002c0, 0x01000, 0x00000000);
    
    timer1 = TIMER_open(TIMER_DEV1,0);
    TIMER_configArgs( timer1, 0x000002c0, 0x00100, 0x00000000);
    
    timer2 = TIMER_open(TIMER_DEV2,0);
    TIMER_configArgs( timer2, 0x000002c0, 0x10000, 0x00000000);  
} /* end ConfigureAllTimers() */

void SelectTimeCriticalInterrupts(void)
{
    int32  TimeCriticalInterrupts=0;
    
    TimeCriticalInterrupts = 0;
    
    TimeCriticalInterrupts |= Interrupt14;
    TimeCriticalInterrupts |= Interrupt15;
    
    DIER = TimeCriticalInterrupts;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -