DSPRelated.com

TI F281x and F2833x ADC Configuration

Emmanuel February 17, 2011 Coded in C for the TI F28x
/**********************************************************************/
#include "DSP281x_Device.h"		//if using F2812
//#include "DSP2833x_Device.h" //if using F28335
/**********************************************************************
void InitAdc(void)
{
	
/*** ADC Reset*/

	AdcRegs.ADCTRL1.bit.RESET = 1;

	asm(" RPT #22 || NOP");		//Wait 2 clocks assuming ADCCLK=12.5 Mhz and SYSCLKOUT=150 Mhz
	
																			
/*** ADC Power-On	*/

	AdcRegs.ADCTRL3.all = 0x00ED;
			
// bit 15-9      0's:    reserved
// bit 8		 0:		 EXTREF
// bit 7-6       11:     ADCBGRFDN, Reference voltage, 00=off, 11=on
// bit 5         1:      ADCPWDN, Main Power Source, 0=off, 1=on
// bit 4-1       0110:   ADCCLKPS, clock prescaler, FCLK=HSPCLK/(2*ADCCLKPS)
// bit 0         1:      SMODE_SEL, 0=sequencial sampling, 1=simultaneous sampling

	DelayUs(5000);			//TI's asm function	
							//Wait 5 ms

/*** ADCMAXCONV	Register configuration*/

	AdcRegs.ADCMAXCONV.all = 0x0000;
	
// bit 15-7      0's:    reserved
// bit 6-4       000:    MAX_CONV2 
// bit 3-0       0000:   MAX_CONV1  (0 = 1 conversion)

/*** Select channels for sampling in SEQ1	*/

	AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0;	//Channels A0 and B0
		
/***  ADCTRL1 Register configuration	*/

	AdcRegs.ADCTRL1.all = 0x0700;
	
// bit 15        0:      reserved
// bit 14        0:      RESET
// bit 13-12     00:     SUSMOD, 00=ignore emulation suspend
// bit 11-8      0111:   ACQ_PS Acquisition window pre-scaler
// bit 7         0:      CPS Core clock
// bit 6         0:      CONT_RUN
// bit 5         0:      SEQ_OVRD
// bit 4         0:      SEQ_CASC
// bit 3-0       0000:   reserved

/*** ADCTRL2 Register configuration	*/

	AdcRegs.ADCTRL2.all = 0x0800;
	
// bit 15        0:      EVB_SOC_SEQ: SOC trigger by EVB
// bit 14        0:      RST_SEQ1: SEQ1 reset
// bit 13        0:      SOC_SEQ1: trigger signal for SEQ1
// bit 12        0:      reserved
// bit 11        1:      INT_ENA_SEQ1: SEQ1 interruption enable
// bit 10        0:      INT_MOD_SEQ1: interruption mode
// bit 9         0:      reserved
// bit 8         0:      EVA_SOC_SEQ1, 1=SEQ1 starts with EVA_SOC trigger
// bit 7         0:      EXT_SOC_SEQ1, 1=SEQ1 starts with ADCSOC input signal
// bit 6         0:      RST_SEQ2
// bit 5         0:      SOC_SEQ2
// bit 4         0:      reserved
// bit 3         0:      INT_ENA_SEQ2: SEQ1 interruption enabled
// bit 2         0:      INT_MOD_SEQ2: interruption mode
// bit 1         0:      reserved
// bit 0         0:      EVB_SOC_SEQ2

/*** ADC interruption enable	*/
PieCtrlRegs.PIEIER1.bit.INTx6= 1;	                 
IER |= 0x0001;              						

}

CRC calculation

Emmanuel February 15, 2011 Coded in C
unsigned char crc(unsigned char data[],int L)
{
	
    unsigned char P=0x83;
    unsigned char *data_ptr;
	unsigned char crc_result;
	int bit;
	crc_result=0;
	for(data_ptr=data;data_ptr<data+L;data_ptr++)
	{
		for(bit=7;bit>=0;bit--)
		{
            crc_result=(crc_result<<1)+((*data_ptr&0x1<<bit)>>bit);
			if (crc_result>=128)
			{
				crc_result=crc_result^P;
			}
		}
	}
	//multiply by 2^n-k;
	for(bit=6;bit>=0;bit--)
		{
            crc_result=(crc_result<<1);
			if (crc_result>=128)
			{
				crc_result=crc_result^P;
			}
		}

	return crc_result;
		
}

Template to develop audio DSP using the (OSS) API + GNU/Linux

Gabriel Rivas February 6, 2011 Coded in C
#include <stdio.h>
#include <fcntl.h>
#include <sys/soundcard.h>

#define BUF_SIZE 2

/*buffers for sound device*/
unsigned char devbuf[BUF_SIZE];

/*File descriptor for device*/
int audio_fd;

/*The sound card is known as the DSP*/
char DEVICE_NAME[]="/dev/dsp";

/*Device Settings*/
int format;
int channels;
int fs;
int len;
int frag;
int devcaps;

int main()
{
    unsigned int temp;
    unsigned int yout;

    /*Samples format is 16 bit unsigned*/
    format = AFMT_U16_LE;
    /*1 Channel, MONO*/
    channels = 1;
    /*Sampling Rate is 16 KHz*/
    fs = 16000;
    /*This is a parameter used to set the DSP for low latencies*/
    frag = 0x00020004;

	/******************************************************
          Set parameters in sound card device
    *****************************************************/

	/*Open sound card device*/
	if ((audio_fd = open(DEVICE_NAME,O_RDWR, 0)) == -1) {
		/* Open of device failed */
		perror(DEVICE_NAME);
		exit(1);
	}	

	if (ioctl (audio_fd, SNDCTL_DSP_SETFRAGMENT, &frag) == -1)
	{
	    perror ("SNDCTL_DSP_SETFRAGMENT");
	    exit (-1);
	}

	/*Set audio format*/
	if (ioctl(audio_fd, SNDCTL_DSP_SETFMT, &format) == -1) {
		/* fatal error */
		perror("SNDCTL_DSP_SETFMT");
		exit(1);
	}
	/*Set number of channels*/
	if (ioctl(audio_fd, SNDCTL_DSP_CHANNELS, &channels) == -1) {
		/* Fatal error */
		perror("SNDCTL_DSP_CHANNELS");
		exit(1);
	}
	
	/*Set sampling rate*/
	if (ioctl(audio_fd, SNDCTL_DSP_SPEED, &fs)==-1) {
		/* Fatal error */
		perror("SNDCTL_DSP_SPEED");
		exit(1);
	}

	if (ioctl(audio_fd, SNDCTL_DSP_SYNC) == -1) {
		/* fatal error */
		perror("SNDCTL_DSP_SYNC");
		exit(1);
	}	

	/******************************************************
          This is the infinite loop to:
          1. Read a sample
          2. Process the sample
          3. Write the sample to soundcard output
    *****************************************************/
    while(1) {
        /* This is a blocking read function, the application will wait
           until the sound card captures a sample
        */
        if ((len = read(audio_fd,devbuf, sizeof(devbuf))) == -1) {
	        perror("audio read");
	        exit(1);
	    }

        /* We can pass this variable to a temporary value, 
           in this case as unsigned 16 value, and then use this value 
           for processing
        */  
	    temp = (devbuf[0])|(devbuf[1]<<8);

        /* In this case no processing is done so the value is passed to the output. You can also use this sample to build an audio file, or send it trought a communications interface, etc.
        */
	    yout = temp;

	    devbuf[0] = yout&0xFF;
	    devbuf[1] = (yout>>8)&0xFF;
		
        /* This is the way the output samples are sent to the soundcard            
        */
        if ((len = write(audio_fd,devbuf,sizeof(devbuf)) == -1)) {
	        perror("audio write");
	        exit(1);
        }
    }	
    return 0;
}

TI F281x SCI Configuration

Emmanuel February 4, 2011 Coded in C for the TI F28x
/**********************************************************************/
#include "DSP281x_Device.h"
/**********************************************************************
* Function: InitSci()
*
* Description:  This function initializes F281x SCI. In this case the desired rate
*				is 9600 bps, 8 databits, 1 stop bit and no parity.
**********************************************************************/
void InitSci(void)
{

/*** SCI reset	*/

	ScibRegs.SCICTL1.bit.SWRESET= 0;
	
/*** Setting the baud rate to 9600 bps assuming LSPCLK=150 Mhz */

	ScibRegs.SCIHBAUD = 0x07;		
	ScibRegs.SCILBAUD = 0xA0;
	

/*** Configuration for no stop bits, no parity and 8 data bits		*/

	ScibRegs.SCICCR.all = 0x07;
	
// bit 7 		0:		STOP BITS
// bit 6 		0:		PARITY
// bit 5 		0:		PARITY ENABLE
// bit 4 		0:		LOOP BACK ENA
// bit 3 		0:		ADDR/IDLE MODE
// bit 2-0 		111:	SCI CHAR

/*** Transmitter and receiver enabled	*/

	ScibRegs.SCICTL1.all = 0x03;
	
// bit 7 		0:		Reserved
// bit 6 		0:		RX ERR INT
// bit 5 		0:		SW RESET
// bit 4 		0		Reserved
// bit 3 		0:		TXWAKE
// bit 2 		0:		SLEEP
// bit 1 		1:		TXENA, Habilitación del transmisor
// bit 0 		1:		RXENA, Habilitación del receptor

/*** Tx and Rx interruption enabled 	*/

	ScibRegs.SCICTL2.all = 0x0003;
	
// bit 7 		0:		TXRDY
// bit 6 		0:		TX EMPTY
// bit 5-2 		0's:	Reserved
// bit 1 		1:		RX/BK INT
// bit 0 		1:		TX INT
	
/***Emulation mode configuration	*/

	ScibRegs.SCIPRI.all = 0x0010;

// bit 7-5 		0's:	Reserved
// bit 4-3 		10:		Emulation Mode
// bit 2-0 		0's:	Reserved

/*** SCI Reset		*/

	ScibRegs.SCICTL1.bit.SWRESET= 1;
	
/*** SCI interruptions enabled in PIE */

	PieCtrlRegs.PIEIER9.bit.INTx4= 1;	  
	PieCtrlRegs.PIEIER9.bit.INTx3= 1;	                
    IER |= 0x0100;              						

}

/**End of file*/

db2_2stages.h - TMX Filter data in C

David Valencia February 2, 2011 Coded in C
// Beginning of file

#define sinc 3 // sincronization factor
#define N 11 // Filter length
#define M 4 // Number of filters(branches)

float h[M][N]={
{
0.0000e+000,
1.6747e-002,
2.9006e-002,
-7.9247e-002,
1.1274e-001,
-2.9575e-001,
-7.9247e-002,
7.6226e-001,
-2.9575e-001,
-4.0401e-001,
2.3325e-001,
},
{
0.0000e+000,
-6.2500e-002,
-1.0825e-001,
2.9575e-001,
-4.2075e-001,
6.7075e-001,
-4.5425e-001,
2.0425e-001,
-7.9247e-002,
-1.0825e-001,
6.2500e-002,
},
{
0.0000e+000,
-6.2500e-002,
-1.0825e-001,
-1.3726e-001,
-1.7075e-001,
3.5377e-001,
7.2877e-001,
-4.5753e-002,
-5.1226e-001,
-1.0825e-001,
6.2500e-002,
},
{
0.0000e+000,
2.3325e-001,
4.0401e-001,
5.1226e-001,
6.3726e-001,
2.9575e-001,
7.9247e-002,
-1.2260e-002,
-1.3726e-001,
-2.9006e-002,
1.6747e-002,
},
};

float g[M][N]={
{
0.0000e+000,
2.3325e-001,
-4.0401e-001,
-2.9575e-001,
7.6226e-001,
-7.9247e-002,
-2.9575e-001,
1.1274e-001,
-7.9247e-002,
2.9006e-002,
1.6747e-002,
},
{
0.0000e+000,
6.2500e-002,
-1.0825e-001,
-7.9247e-002,
2.0425e-001,
-4.5425e-001,
6.7075e-001,
-4.2075e-001,
2.9575e-001,
-1.0825e-001,
-6.2500e-002,
},
{
0.0000e+000,
6.2500e-002,
-1.0825e-001,
-5.1226e-001,
-4.5753e-002,
7.2877e-001,
3.5377e-001,
-1.7075e-001,
-1.3726e-001,
-1.0825e-001,
-6.2500e-002,
},
{
0.0000e+000,
1.6747e-002,
-2.9006e-002,
-1.3726e-001,
-1.2260e-002,
7.9247e-002,
2.9575e-001,
6.3726e-001,
5.1226e-001,
4.0401e-001,
2.3325e-001,
},
};

// EOF

Interrupt.c - DSK6713 External Interruptions via GPIO

David Valencia February 2, 20111 comment Coded in C for the TI C67x
/* Interruption.c 
JOSE DAVID VALENCIA PESQUEIRA
UPIITA-IPN 
THIS PROGRAM DETECTS AN EXTERNAL INTERRUPTION ON A GPIO PIN*/ 

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
#include <time.h> 
#include <csl_gpio.h> 
#include <csl_gpiohal.h> 
#include <csl_irq.h> 

/* GLOBAL VARIABLES
The flags are marked as volatile, to tell the compiler
that these can be modified by an external event, avoiding
to put them on registers and rather putting them on RAM
so they're ready for immediate use
*/

volatile int startflag = 0; 

GPIO_Handle gpio_handle;  /* Handle for the GPIO */ 

// GPIO Registers configuration

GPIO_Config gpio_config = {          
	0x00000000,  
	// gpgc = Interruption passtrhrough mode and direct GPIO control mode
	0x0000FFFF, // gpen = All GPIO 0-15 pins enabled
	0x00000000, // gdir = All GPIO pins as inputs
	0x00000000, // gpval = Stores logical level of pins
	0x00000010, // IRQ enable for pin 4
	0x00000010, // Enable Event for pin 4
	0x00000000  // gppol -- default state  
}; 

irq_ext_enable(){ 
	/* First, globally disable interruptions
	in the CSR (Control Status Register).
	Bit 0 is the GIE (Global Interrupt Enable)*/
	CSR = (CSR)&(0xFFFFFFFE); 
	// Enable NMIE bit in the IER (bit 1)
	IER |= 0x00000002; 
	// Enable INT4 bit in the IER (4th bit)
	IER |= 0x00000010; 
	// Finally, globally enable interruptions in the CSR
	CSR |= 0x00000001; 
} 

main() 
{      
	// To configure the GPIO
	gpio_handle = GPIO_open( GPIO_DEV0, GPIO_OPEN_RESET ); 
	GPIO_config(gpio_handle,&gpio_config); 
	irq_ext_enable(); 
	comm_intr();      //init DSK 
	DSK6713_LED_init(); 
	while(startflag == 0);  
	printf(“La interrupción externa encendió el led 3 del dsk6713\n”); 
	while(1) // Infinite While
}    

interrupt void c_int04()           //ISR 
{ 
	startflag = 1; 
	iter = 0; 
	DSK6713_LED_on(0);   //To turn on the led
}

GPIO.c - Using the GPIO as output

David Valencia January 31, 20114 comments Coded in C for the TI C67x
// GPIO.c	UPIITA-IPN 
// JOSE DAVID VALENCIA PESQUEIRA
//
// THIS PROGRAM ALLOWS THE DSP TO SEND A BIT THROUGH A GPIO PIN (PIN 7 IN THIS EXAMPLE)
// TO TURN ON A LED ON

#include <stdio.h>
#include <stdlib.h>
#include <csl_gpio.h>
#include <csl_gpiohal.h>
#include <csl_irq.h>

// GLOBAL VARIABLES
volatile int flag = 1;
volatile int pulse_flag = 1;

// CODE TO DEFINE GPIO HANDLE
GPIO_Handle gpio_handle; 

// GPIO REGISTER CONFIGURATION
GPIO_Config gpio_config = {         
    0x00000000, // gpgc = Interruption passthrough mode
    0x0000FFFF, // gpen = All GPIO 0-15 pins enabled
    0x0000FFFF, // gdir = All GPIO pins as outputs
    0x00000000, // gpval = Saves the logical states of pins
    0x00000000, // gphm All interrupts disabled for IO pins
    0x00000000, // gplm All interrupts for CPU EDMA disabled
    0x00000000  // gppol -- default state */
};

// Function prototypes
void send_edge();
void delay();

// Function definitions
void delay()
{
	// Delay function
	int count, count2;
	for(count = 0; count < 200; count++)
	{
		for(count2 = 0; count2 < 50000; count2++);
	}
}

void send_edge()
{	
    DSK6713_init();  
    // Open and configure the GPIO
    gpio_handle = GPIO_open( GPIO_DEV0, GPIO_OPEN_RESET );
    GPIO_config(gpio_handle,&gpio_config);
    // Send values through the pins
	
    GPIO_pinWrite(gpio_handle,GPIO_PIN7,0);
    delay();
    GPIO_pinWrite(gpio_handle,GPIO_PIN7,1);
    delay();
    GPIO_pinWrite(gpio_handle,GPIO_PIN7,0);
}

main()
{     
	send_edge(); // Configures the pins and sends a rising edge
	printf(“ ¡Felicidades! ¡Has logrado encender el led! ”);
	
}
// End of program>>

Inverse Sqrt and Fourth Root approximations

January 31, 2011 Coded in C for the SHARC
// Fast InvSqrt approxumation, with an error of less than 4%. 
// This approximation is attributed to Greg Walsh.
inline void InvSqrt(float *x) {	*(int *)x = 0x5f3759df - (*(int *)x >> 1); } 
inline float SqrtSqrt(float x) { InvSqrt(&x); InvSqrt(&x); return x; }

Fast power-of-10 approximation, for 32-bit floats

January 31, 2011 Coded in C for the SHARC
// Fast power-of-10 approximation, with RMS error of 1.77%. 
// This approximation developed by Nicol Schraudolph (Neural Computation vol 11, 1999).  
// Adapted for 32-bit floats by Lippold Haken of Haken Audio, April 2010.
// Set float variable's bits to integer expression.
// f=b^f is approximated by
//   (int)f = f*0x00800000*log(b)/log(2) + 0x3F800000-60801*8
// f=10^f is approximated by
//   (int)f = f*27866352.6 + 1064866808.0
inline void Pow10(float *f) { *(int *)f = *f * 27866352.6 + 1064866808.0; };

Fractional Delay Line implementation

Gabriel Rivas January 27, 20113 comments Coded in C
/****************DELAY.C*******************************/
#include "delay.h"
#include "math.h"

#define MAX_BUF_SIZE 64000

/*****************************************************************************
*       Fractional delay line implementation in C:
*
*                    ---------[d_mix]--------------------------
*                    |                                         |
*                    |                                         |
*                    |x1                                       v
*     xin ------>[+]----->[z^-M]--[interp.]----[d_fw]-------->[+]-----> yout 
*                 ^                         |  
*                 |                         |
*                 |----------[d_fb]<--------|   
*******************************************************************************/

double d_buffer[MAX_BUF_SIZE];

/*
This interface defines the delay object
*/
static struct fract_delay {
    double d_mix;       /*delay blend parameter*/
    short d_samples;	/*delay duration in samples*/
    double d_fb;	    /*feedback volume*/
    double d_fw;	    /*delay tap mix volume*/
    double n_fract;     /*fractional part of the delay*/
    double *rdPtr;      /*delay read pointer*/
    double *wrtPtr;     /*delay write pointer*/
};

static struct fract_delay del;

/*
This function is used to initialize the delay object
*/
void Delay_Init(double delay_samples,double dfb,double dfw, double dmix) {
	Delay_set_delay(delay_samples);
	Delay_set_fb(dfb);
	Delay_set_fw(dfw);
	Delay_set_mix(dmix);	
	del.wrtPtr = &d_buffer[MAX_BUF_SIZE-1];
}

/*
These functions are used as interface to the delay object,
so there's not direct access to the delay object from
external modules
*/
void Delay_set_fb(double val) {
    del.d_fb = val;
}

void Delay_set_fw(double val) {
    del.d_fw = val;
}

void Delay_set_mix(double val) {
    del.d_mix = val;
}

void Delay_set_delay(double n_delay) {
    /*Get the integer part of the delay*/
    del.d_samples = (short)floor(n_delay);

    /*gets the fractional part of the delay*/
    del.n_fract = (n_delay - del.d_samples);	
}

double Delay_get_fb(void) {
    return del.d_fb;
}

double Delay_get_fw(void) {
    return del.d_fw;
}

double Delay_get_mix(void) {
    return del.d_mix;
}

/*
This is the main delay task,
*/
double Delay_task(double xin) {
	double yout;
	double * y0; 
	double * y1;
	double x1;
	double x_est;
    
    /*Calculates current read pointer position*/
	del.rdPtr = del.wrtPtr - (short)del.d_samples;
	
	/*Wraps read pointer*/
	if (del.rdPtr < d_buffer) {
		del.rdPtr += MAX_BUF_SIZE-1;
	}
	
	/*Linear interpolation to estimate the delay + the fractional part*/
	y0 = del.rdPtr-1;
	y1 = del.rdPtr;

	if (y0 < d_buffer) {
	    y0 += MAX_BUF_SIZE-1;
	}

	x_est = (*(y0) - *(y1))*del.n_fract + *(y1);

    /*Calculate next value to store in buffer*/
    x1 = xin + x_est*del.d_fb;
    
	/*Store value in buffer*/
	*(del.wrtPtr) = x1;
  
    /*Output value calculation*/
	yout = x1*del.d_mix + x_est*del.d_fw;

    /*Increment delat write pointer*/
	del.wrtPtr++;

    /*Wraps delay write pointer*/
	if ((del.wrtPtr-&d_buffer[0]) > MAX_BUF_SIZE-1) {
		del.wrtPtr = &d_buffer[0];
	}
	return yout;
}
/***********DELAY.h*************************************/
#ifndef __DELAY_H__
#define __DELAY_H__

void Delay_Init(double delay_samples,double dfb,double dfw, double dmix);
void Delay_set_fb(double val);
void Delay_set_fw(double val);
void Delay_set_mix(double val);
void Delay_set_delay(double n_delay);
double Delay_get_fb(void);
double Delay_get_fw(void);
double Delay_get_mix(void);
double Delay_task(double xin);

#endif
/*****USAGE EXAMPLE****************************************/
void main(void) {
    double xin;
    double yout;
    Delay_Init(85.6,0.7,0.7,1);

    while(1) { 
        if (new_sample_flag()) {
            /*When there's new sample at your ADC or CODEC input*/
            /*Read the sample*/
            xin = read_sample();
            /*Apply the Delay_task function to the sample*/
            yout = Delay_task(xin);

            /*Send the output value to your ADC or codec output*/
            write_output(yout);
        }				
    }
}