///////////////////////////////////////////////////////////////////////
// Filename: ISRs.c
//
// Synopsis: Perform Linear and Nonlinear Wavelet Denoising
// using TI TMS320C6711 DSK w/ eDSP Stereo CODEC
//
// Author: Nash Borges
// ISR Shell: Michael G. Morrow
//
// Date of Last Revision: 2003-12-11
///////////////////////////////////////////////////////////////////////
void convleftdown(float *DOut,float *Cout, float *Cin, int count);
void upconvright(float *COut, float *DIn, float *CIn, int count);
void zerocolumns(float *DFirst, float *DSecond, float *DThird, float *DFourth, float *CFourth);
void thresholding(float *DFirst, float *DSecond, float *DThird, float *DFourth, float *CFourth);

#include "DSK_Config.h"
#include "frames.h"
#include "bior68coeffs.h"
#include "hpi.h"

// frame buffer declarations
#define BUFFER_COUNT 1024 // buffer length in McBSP samples (L+R)
#define BUFFER_LENGTH BUFFER_COUNT*2 // two shorts read from McBSP each time
#define NUM_BUFFERS 3 // don't change this!

#pragma DATA_SECTION (buffer, "CE0"); // allocate buffers in SDRAM
//#pragma DATA_SECTION (CLeftZero, "CE0");

short buffer[NUM_BUFFERS][BUFFER_LENGTH];

// there are 3 buffers in use at all times, one being filled from the McBSP,
// one being operated on, and one being emptied to the McBSP
// ready_index --> buffer ready for processing

float CLeftZero[BUFFER_COUNT<<1],
CLeftFirst[BUFFER_COUNT], DLeftFirst[BUFFER_COUNT],
CLeftSecond[BUFFER_COUNT>>1], DLeftSecond[BUFFER_COUNT>>1],
CLeftThird[BUFFER_COUNT>>2], DLeftThird[BUFFER_COUNT>>2],
CLeftFourth[BUFFER_COUNT>>3], DLeftFourth[BUFFER_COUNT>>3];
volatile short buffer_ready = 0, over_run = 0, ready_index = 0;

void EDMA_Init()
////////////////////////////////////////////////////////////////////////
// Purpose: Configure EDMA controller to perform all McBSP servicing.
// EDMA is setup so buffer[2] is outbound to McBSP, buffer[0] is
// available for processing, and buffer[1] is being loaded.
// Conditional statement ensure that the correct EDMA events are
// used based on the McBSP that is being used.
// Both the EDMA transmit and receive events are set to automatically
// reload upon completion, cycling through the 3 buffers.
// The EDMA completion interrupt occurs when a buffer has been filled
// by the EDMA from the McBSP.
// The EDMA interrupt service routine updates the ready buffer index,
// and sets the buffer ready flag which is being polled by the main
// program loop
//
// Input: None
//
// Returns: Nothing
//
// Calls: Nothing
//
// Notes: None
///////////////////////////////////////////////////////////////////////
{
EDMA_params* param;

// McBSP tx event params
param = (EDMA_params*)((CodecType == TLC320AD535)?EVENTC_PARAMS:EVENTE_PARAMS);
param->options = 0x211E0002;
param->source = (unsigned int)(&buffer[2][0]);
param->count = (0 << 16) + (BUFFER_COUNT);
param->dest = (CodecType == TLC320AD535)?0x30000000:0x34000000;
param->reload_link = (BUFFER_COUNT << 16) + (EVENTN_PARAMS & 0xFFFF);

// set up first tx link param
param = (EDMA_params*)EVENTN_PARAMS;
param->options = 0x211E0002;
param->source = (unsigned int)(&buffer[0][0]);
param->count = (0 << 16) + (BUFFER_COUNT);
param->dest = (CodecType == TLC320AD535)?0x30000000:0x34000000;
param->reload_link = (BUFFER_COUNT << 16) + (EVENTO_PARAMS & 0xFFFF);

// set up second tx link param
param = (EDMA_params*)EVENTO_PARAMS;
param->options = 0x211E0002;
param->source = (unsigned int)(&buffer[1][0]);
param->count = (0 << 16) + (BUFFER_COUNT);
param->dest = (CodecType == TLC320AD535)?0x30000000:0x34000000;
param->reload_link = (BUFFER_COUNT << 16) + (EVENTP_PARAMS & 0xFFFF);

// set up third tx link param
param = (EDMA_params*)EVENTP_PARAMS;
param->options = 0x211E0002;
param->source = (unsigned int)(&buffer[2][0]);
param->count = (0 << 16) + (BUFFER_COUNT);
param->dest = (CodecType == TLC320AD535)?0x30000000:0x34000000;
param->reload_link = (BUFFER_COUNT << 16) + (EVENTN_PARAMS & 0xFFFF);

// McBSP rx event params
param = (EDMA_params*)((CodecType == TLC320AD535)?EVENTD_PARAMS:EVENTF_PARAMS);
param->options = 0x203F0002;
param->source = (CodecType == TLC320AD535)?0x30000000:0x34000000;
param->count = (0 << 16) + (BUFFER_COUNT);
param->dest = (unsigned int)(&buffer[1][0]);
param->reload_link = (BUFFER_COUNT << 16) + (EVENTQ_PARAMS & 0xFFFF);

// set up first rx link param
param = (EDMA_params*)EVENTQ_PARAMS;
param->options = 0x203F0002;
param->source = (CodecType == TLC320AD535)?0x30000000:0x34000000;
param->count = (0 << 16) + (BUFFER_COUNT);
param->dest = (unsigned int)(&buffer[2][0]);
param->reload_link = (BUFFER_COUNT << 16) + (EVENTR_PARAMS & 0xFFFF);

// set up second rx link param
param = (EDMA_params*)EVENTR_PARAMS;
param->options = 0x203F0002;
param->source = (CodecType == TLC320AD535)?0x30000000:0x34000000;
param->count = (0 << 16) + (BUFFER_COUNT);
param->dest = (unsigned int)(&buffer[0][0]);
param->reload_link = (BUFFER_COUNT << 16) + (EVENTS_PARAMS & 0xFFFF);

// set up third rx link param
param = (EDMA_params*)EVENTS_PARAMS;
param->options = 0x203F0002;
param->source = (CodecType == TLC320AD535)?0x30000000:0x34000000;
param->count = (0 << 16) + (BUFFER_COUNT);
param->dest = (unsigned int)(&buffer[1][0]);
param->reload_link = (BUFFER_COUNT << 16) + (EVENTQ_PARAMS & 0xFFFF);

*(unsigned volatile int *)ECR = 0xf000; // clear all McBSP events
*(unsigned volatile int *)EER = (CodecType == TLC320AD535)?0x3000:0xC000;
*(unsigned volatile int *)CIER = 0x8000; // interrupt on rx reload only
}

void ZeroBuffers()
////////////////////////////////////////////////////////////////////////
// Purpose: Sets all buffer locations to 0
//
// Input: None
//
// Returns: Nothing
//
// Calls: Nothing
//
// Notes: None
///////////////////////////////////////////////////////////////////////
{
int i = BUFFER_COUNT * NUM_BUFFERS;
int *p = (int *)buffer;

while(i--)
*p++ = 0;
}

void ProcessBuffer()
///////////////////////////////////////////////////////////////////////
// Purpose: Processes the data in buffer[ready_index] and stores
// the results back into the buffer
// Data is packed into the buffer, alternating right/left
//
// Input: None
//
// Returns: Nothing
//
// Calls: Nothing
//
// Notes: None
///////////////////////////////////////////////////////////////////////
{
short *pBuf = buffer[ready_index];
// extra buffer room for convolution "edge effects" by mirroring input
float *pL = CLeftZero, *pLL = CLeftZero, *pLR = CLeftZero;
int i;

///////////////////////////////////////////////////////////////////////
// Begin Processing
///////////////////////////////////////////////////////////////////////

// offset pointers to start mirroring
pL += (BUFFER_COUNT>>1); // buffer_count/2
pLL += (BUFFER_COUNT>>1) - 1; // buffer_count/2 - 1
pLR += (BUFFER_COUNT<<1) - 1; // buffer_count*2 - 1

// extract data from shorts in buffer to floats in Left and mirror Left.
// order is important here: must go right first then left.
for(i = 0; i<=BUFFER_COUNT-1; i++) {
// skip right
*pBuf++;

// mirroring
if (i < (BUFFER_COUNT>>1))
*pLL-- = *pBuf;
else
*pLR-- = *pBuf;

// fill Left
*pL++ = *pBuf++;
}

// reset pointer
pBuf = buffer[ready_index];

// analysis
convleftdown(DLeftFirst, CLeftFirst, CLeftZero, BUFFER_COUNT<<1);
convleftdown(DLeftSecond, CLeftSecond, CLeftFirst, BUFFER_COUNT);
convleftdown(DLeftThird, CLeftThird, CLeftSecond, BUFFER_COUNT>>1);
convleftdown(DLeftFourth, CLeftFourth, CLeftThird, BUFFER_COUNT>>2);

// denoising
zerocolumns(DLeftFirst, DLeftSecond, DLeftThird, DLeftFourth, CLeftFourth);
if (HPI_Block.Threshold > 0)
thresholding(DLeftFirst, DLeftSecond, DLeftThird, DLeftFourth, CLeftFourth);

// resynthesis
upconvright(CLeftThird, DLeftFourth, CLeftFourth, BUFFER_COUNT>>2);
upconvright(CLeftSecond, DLeftThird, CLeftThird, BUFFER_COUNT>>1);
upconvright(CLeftFirst, DLeftSecond, CLeftSecond, BUFFER_COUNT);
upconvright(CLeftZero, DLeftFirst, CLeftFirst, BUFFER_COUNT<<1);


// extract middle of mirror
for(i=BUFFER_COUNT>>1; i<=(BUFFER_COUNT + (BUFFER_COUNT>>1) - 1); i++) {// keep right
*pBuf++ = _spint(CLeftZero[i] * 65536) >> 16;
*pBuf++ = _spint(CLeftZero[i] * 65536) >> 16;
}



///////////////////////////////////////////////////////////////////////
// End Processing
///////////////////////////////////////////////////////////////////////

// reinitialize pointer
pBuf = buffer[ready_index];

if(CodecType == TLC320AD535) { // mask off LSB to prevent codec reprogramming
for(i = 0;i < BUFFER_COUNT;i++) {
*(unsigned int *)pBuf &= 0xfffffffe;
pBuf += 2;
}
}

buffer_ready = 0; //signal we are done
}

///////////////////////////////////////////////////////////////////////
// Purpose: Convolve, Keep Left, and Downsample
//
// Input: Cin
//
// Returns: Dout, Cout
//
// Calls: Nothing
//
// Notes: None
///////////////////////////////////////////////////////////////////////
void convleftdown(float *DOut,float *COut, float *CIn, int count)
{
float dsum, csum;
int i,j,k;


// convolve, keep left, and downsample
for(i=0; i<=count-1; i+=2) { // keep left
dsum = 0; // initialize the D coefficient
csum = 0; // initialize the C Coefficient

// dot product
for(j=0,k=i; j<=N; j++,k--) {
if ((j<=i) && (k<=count-1)) {
dsum += CIn[k] * H1FLIP[j]; // convolve input with H1flip
csum += CIn[k] * H0FLIP[j]; // convolve input with H0flip
}
}

// store downsampled
j = i>>1;
DOut[j] = dsum;
COut[j] = csum;
}

}

///////////////////////////////////////////////////////////////////////
// Purpose: Upsample, Convolve, and Keep Right
//
// Input: Din, Cin
//
// Returns: Dout
//
// Calls: Nothing
//
// Notes: None
///////////////////////////////////////////////////////////////////////
void upconvright(float *COut, float *DIn, float *CIn, int count)
{
float dsum, csum;
int i,j,k,test;

// upsample, convolve, and keep right
for(i=N; i<=count+N-1; i++) { // keep right
dsum = 0; // initialize the D coefficient
csum = 0; // initialize the C coefficient

// dot product
for(j=0,k=i; j<=N; j++,k--) {
test = (k << 31) >> 31; // test if k is even, this does "upsampling"
if ((j<=i) && (k<=count-1) && (test==0)) {
dsum += DIn[k>>1] * H1[j]; // convolve upsampled with H1
csum += CIn[k>>1] * H0[j]; // convolve upsampled with H0
}
}

// store
csum += dsum;
COut[i-N] = csum;
}
}
///////////////////////////////////////////////////////////////////////
// Purpose: Zero Columns of DWT (linear de-noising)
//
// Input: DFirst, DSecond, DThird, DFourth
//
// Returns: DFirst, DSecond, DThird, DFourth
//
// Calls: Nothing
//
// Notes: None
///////////////////////////////////////////////////////////////////////
void zerocolumns(float *DFirst, float *DSecond, float *DThird, float *DFourth, float *CFourth)
{
int i;

if ((short)HPI_Block.Col1)
for (i=0; i DFirst[i] = 0;
if ((short)HPI_Block.Col2)
for (i=0; i<(BUFFER_COUNT>>1); i++)
DSecond[i] = 0;
if ((short)HPI_Block.Col3)
for (i=0; i<(BUFFER_COUNT>>2); i++)
DThird[i] = 0;
if ((short)HPI_Block.Col4)
for (i=0; i<(BUFFER_COUNT>>3); i++)
DFourth[i] = 0;
if ((short)HPI_Block.Col5)
for (i=0; i<(BUFFER_COUNT>>3); i++)
CFourth[i] = 0;
}

///////////////////////////////////////////////////////////////////////
// Purpose: Zero coefficients below threshold (non-linear de-noising)
//
// Input: DFirst, DSecond, DThird, DFourth
//
// Returns: DFirst, DSecond, DThird, DFourth
//
// Calls: Nothing
//
// Notes: None
///////////////////////////////////////////////////////////////////////
void thresholding(float *DFirst, float *DSecond, float *DThird, float *DFourth, float *CFourth)
{
float adjthreshold = HPI_Block.Threshold*32768.0;
int i;

for (i=0; i if ((DFirst[i] >= -adjthreshold) && (DFirst[i] <= adjthreshold))
DFirst[i] = 0;
else if ((short)HPI_Block.SoftThresholding) {
if (DFirst[i] > 0)
DFirst[i] = DFirst[i] - adjthreshold;
else
DFirst[i] = DFirst[i] + adjthreshold;
}
for (i=0; i<(BUFFER_COUNT>>1); i++)
if ((DSecond[i] >= -adjthreshold) && (DSecond[i] <= adjthreshold))
DSecond[i] = 0;
else if ((short)HPI_Block.SoftThresholding) {
if (DSecond[i] > 0)
DSecond[i] = DSecond[i] - adjthreshold;
else
DSecond[i] = DSecond[i] + adjthreshold;
}
for (i=0; i<(BUFFER_COUNT>>2); i++)
if ((DThird[i] >= -adjthreshold) && (DThird[i] <= adjthreshold))
DThird[i] = 0;
else if ((short)HPI_Block.SoftThresholding) {
if (DThird[i] > 0)
DThird[i] = DThird[i] - adjthreshold;
else
DThird[i] = DThird[i] + adjthreshold;
}
for (i=0; i<(BUFFER_COUNT>>3); i++)
if ((DFourth[i] >= -adjthreshold) && (DFourth[i] <= adjthreshold))
DFourth[i] = 0;
else if ((short)HPI_Block.SoftThresholding) {
if (DFourth[i] > 0)
DFourth[i] = DFourth[i] - adjthreshold;
else
DFourth[i] = DFourth[i] + adjthreshold;
}
for (i=0; i<(BUFFER_COUNT>>3); i++)
if ((CFourth[i] >= -adjthreshold) && (CFourth[i] <= adjthreshold))
CFourth[i] = 0;
else if ((short)HPI_Block.SoftThresholding) {
if (CFourth[i] > 0)
CFourth[i] = CFourth[i] - adjthreshold;
else
CFourth[i] = CFourth[i] + adjthreshold;
}
}

///////////////////////////////////////////////////////////////////////
// Purpose: Access function for buffer ready flag
//
// Input: None
//
// Returns: Non-zero when a buffer is ready for processing
//
// Calls: Nothing
//
// Notes: None
///////////////////////////////////////////////////////////////////////
int IsBufferReady()
{
return buffer_ready;
}

///////////////////////////////////////////////////////////////////////
// Purpose: Access function for buffer overrun flag
//
// Input: None
//
// Returns: Non-zero if a buffer overrun has occurred
//
// Calls: Nothing
//
// Notes: None
///////////////////////////////////////////////////////////////////////
int IsOverRun()
{
return over_run;
}

interrupt void EDMA_ISR()
///////////////////////////////////////////////////////////////////////
// Purpose: EDMA interrupt service routine. Invoked on every buffer
// completion
//
// Input: None
//
// Returns: Nothing
//
// Calls: Nothing
//
// Notes: None
///////////////////////////////////////////////////////////////////////
{
*(unsigned volatile int *)CIPR = 0xf000; // clear all McBSP events
if(++ready_index >= NUM_BUFFERS) // update buffer index
ready_index = 0;
if(buffer_ready == 1) // set a flag if buffer isn't processed in time
over_run = 1;
buffer_ready = 1; // mark buffer as ready for processing
}
nashborges Valid XHTML Valid CSS