Reply by CyRex February 25, 20052005-02-25
True, there are some other things than need to be done so that the
SHARC interprets and stores/processes the input signals correctly when
the sample rate is not 48kHz, but changing the register is what will
actually set the sample rate of the codec.  How the SHARC deals with
the incoming samples is a different story...

-CyRex

Reply by February 25, 20052005-02-25
Hi Guys,

Beware that it is not simply changing the register what works for this
particular CODEC.

There was an extremely interesting document in ADI website title
"Interfacing the ADSP21065L SHARC DSP to the AD1819A AC-97 Soundport
Codec", which you can get from here:

http://www.analog.com/UploadedFiles/Application_Notes/250806129AD1819A_21065L.pdf

It very thoroughly explains how to do it.

I have a C version of this. If you want it, I'd be glad to share it.

Please write to me at soporte@sanjaac.com, and I will send it in a few
hours (I don't have it right here).

Regards,

JaaC


CyRex wrote:
> Marek... > > This the register addresses for the audio codec are defined in the > section "CONSTANT & MACRO DEFINITIONS". You will want to add the > following values to that section: > > ********************** > #define SAMPLE_RATE_8KHZ 0x401F > > #define SAMPLE_RATE0_ADDR 0x7800 > #define SAMPLE_RATE1_ADDR 0x7A00 > ********************** > > 78h and 7Ah are the addresses for the registers that control the
sample
> rates. The setting for 8kHz is 8000 in hex, or 1F40 (swapped in the > SHARC so its 401F). This will define your contants. > > Next, in the procedure init_codec(), you need to send the correct > commands to initialize the codec: > > *********************** > /* Set Sample Rate 0 to 8kHz */ > user_tx_buf[TAG] = REGOUT_TAG; > user_tx_buf[ADDR] = SAMPLE_RATE0_ADDR; > user_tx_buf[DATA] = SAMPLE_RATE_8KHZ; > user_tx_ready = 1; /* Tell the isr that txbuf is
ready
> */ > idle(); > idle(); > > /* Set Sample Rate 1 to 8kHz */ > user_tx_buf[TAG] = REGOUT_TAG; > user_tx_buf[ADDR] = SAMPLE_RATE1_ADDR; > user_tx_buf[DATA] = SAMPLE_RATE_8KHZ; > user_tx_ready = 1; /* Tell the isr that txbuf is
ready
> */ > idle(); > idle(); > *********************** > > I haven't worked with the SHARC in 3 years or so, and this is mostly > from memory, so it may not be exactly right. If you need any more > reference, check out this link: > >
http://www.analog.com/UploadedFiles/Obsolete_Data_Sheets/1809887AD1819A.pdf
> > Good Luck! > - CyRex
Reply by CyRex February 25, 20052005-02-25
Marek...

This the register addresses for the audio codec are defined in the
section "CONSTANT & MACRO DEFINITIONS".  You will want to add the
following values to that section:

**********************
#define SAMPLE_RATE_8KHZ      0x401F

#define SAMPLE_RATE0_ADDR     0x7800
#define SAMPLE_RATE1_ADDR     0x7A00
**********************

78h and 7Ah are the addresses for the registers that control the sample
rates.  The setting for 8kHz is 8000 in hex, or 1F40 (swapped in the
SHARC so its 401F).  This will define your contants.

Next, in the procedure init_codec(), you need to send the correct
commands to initialize the codec:

***********************
/* Set Sample Rate 0 to 8kHz */
user_tx_buf[TAG] = REGOUT_TAG;
user_tx_buf[ADDR] = SAMPLE_RATE0_ADDR;
user_tx_buf[DATA] = SAMPLE_RATE_8KHZ;
user_tx_ready = 1;                 /* Tell the isr that txbuf is ready
*/
idle();
idle();

/* Set Sample Rate 1 to 8kHz */
user_tx_buf[TAG] = REGOUT_TAG;
user_tx_buf[ADDR] = SAMPLE_RATE1_ADDR;
user_tx_buf[DATA] = SAMPLE_RATE_8KHZ;
user_tx_ready = 1;                 /* Tell the isr that txbuf is ready
*/
idle();
idle();
***********************

I haven't worked with the SHARC in 3 years or so, and this is mostly
from memory, so it may not be exactly right.  If you need any more
reference, check out this link:

http://www.analog.com/UploadedFiles/Obsolete_Data_Sheets/1809887AD1819A.pdf

Good Luck!  
- CyRex

Reply by Jerry Avins February 25, 20052005-02-25
Marek wrote:
> Hello, everybody. I'm just a beginner. I use ADSP-21065L SHARC EZ-KIT Lite > where is codec AD1819A. The default sampling rate is 48 kHz and I need to > change it. But it's so difficult for me to do it. I would like to change > it for example from 48 kHz to 8 kHz. Please help me if you can. > Thank you very much > Marek
... I don't have the manual handy, nor am I sure it can be done (but I'd be surprised if not). As a quick fix until something better comes along, you can simply use one sample out of six and throw the other five away. Jerry -- Engineering is the art of making what you want from things you can get. �����������������������������������������������������������������������
Reply by Marek February 25, 20052005-02-25
Hello, everybody. I'm just a beginner. I use ADSP-21065L SHARC EZ-KIT Lite
where is codec AD1819A. The default sampling rate is 48 kHz and I need to
change it. But it's so difficult for me to do it. I would like to change
it for example from 48 kHz to 8 kHz. Please help me if you can. 
Thank you very much
Marek

The code:
/*--------------------------------------------------------------------------
    INCLUDES
--------------------------------------------------------------------------*/
#include <def21060.h>
#include <21065l.h>
#include <signal.h>
#include <macros.h>
#include <math.h>
#include <filters.h>
#include <ezkit/1819regs.h>

/*--------------------------------------------------------------------------
   CONSTANT & MACRO DEFINITIONS
--------------------------------------------------------------------------*/
/* Codec tag word to send out left and right samples */
#define DOUT_TAG         0x9800

/* Codec tag word to send out address and data slots */
#define REGOUT_TAG       0xe000

/* This is the codec register setting for line input on both channels */
#define SOURCE_IS_LINE   0x0404
#define SOURCE_IS_MIC    0

/* Codec addreses */
#define SOURCE_ADDR      0x1a00
#define RECGAIN_ADDR     0x1c00

#define CODEC_ISR_VECT 0X9001

/*--------------------------------------------------------------------------
   EXTERNAL DECLARATIONS
--------------------------------------------------------------------------*/
/* These compile to the same addresses as in the kernel if the .ldf is
set
   up correctly  */
extern volatile int user_tx_buf[6];
extern volatile int user_tx_ready;
extern volatile int user_rx_buf[6];
extern volatile int user_rx_ready;

/*--------------------------------------------------------------------------
   FUNCTION PROTOTYPES
--------------------------------------------------------------------------*/
void init_codec(void);
void main (void);

/****************************************************************************
**
** Procedure:  main()
**
** Arguments:  None
**
** Returns:    None
**
** Desc:       main code
**
****************************************************************************/
void main ( void )
{
    float filter_input;

    // Initialize some codec registers.
    init_codec();

    // Loop forever.
   
   user_tx_ready = 0;
   for(;;)
   {
      user_rx_ready = 1;
      idle();
      while (user_rx_ready);
      while (user_tx_ready);
 
      // Get sample from Codec or random noise.    
      filter_input = user_rx_buf[RIGHT_CHNL];

      // Output.
      user_tx_buf[RIGHT_CHNL] = filter_input;
      user_tx_buf[LEFT_CHANL] = user_tx_buf[RIGHT_CHNL];
      user_tx_buf[TAG] = DOUT_TAG;
      user_tx_ready = 1;
   };
}

/****************************************************************************
**
** Procedure:  init_codec()
**
** Arguments:  None
**
** Returns:    None
**
** Desc:       Unmasks the sport1 interrupt and uses the kernel isr
**             to initialize the codec input source and record gain.
**
****************************************************************************/
void init_codec( void )
{
   asm("#include <def21065l.h>");
   interrupt(SIG_SPT1I,(void (*)(int))CODEC_ISR_VECT);
   asm("BIT SET IMASK SPT1I;");   /* unmasks sport interrupt */
    
   /* Set source to LINE */
   user_tx_buf[TAG] = REGOUT_TAG;
   user_tx_buf[ADDR] = SOURCE_ADDR;
   user_tx_buf[DATA] = SOURCE_IS_LINE;
   user_tx_ready = 1;                 /* Tell the isr that txbuf is ready
*/
   idle();
   idle();

   /* Set record gain */
   user_tx_buf[TAG] = REGOUT_TAG;
   user_tx_buf[ADDR] = RECGAIN_ADDR;
   user_tx_buf[DATA] = 0;
   user_tx_ready = 1;                 /* Tell the isr that txbuf is ready
*/
   idle();
   idle();
  
   return;
}


****************************************************************************
**                       $TITLE: BUFFERS.ASM$
** BUFFERS.ASM
** ---------
**    Links variables into the same locations the kernel uses so that
**    the demo can talk to the kernel to use its codec isr or output SWI
**    
**
****************************************************************************/
GLOBAL _user_tx_buf;
GLOBAL _user_tx_ready;
GLOBAL _user_rx_buf;
GLOBAL _user_rx_ready;
GLOBAL _user_data_out_ptr; 
GLOBAL _user_num_data;     
GLOBAL _user_data_type;    

SEGMENT/DM     seg_bnk3;
// make the buffers line up the same as in the kernel
var _user_tx_buf[6];
var _user_tx_ready;
var _user_rx_buf[6];
var _user_rx_ready;
var _user_data_out_ptr;    //pointer to data to send to the host
var _user_num_data;        //says how many data items there are
var _user_data_type;       // 0 = ascii, 1 = decimal, 2 = hex

ENDSEG;
    

/* This file contains the interrupt table for the ADSP-21065L		*/

/* When the C program exits either by returning from main() or by an 	*/
/* explicit or implicit call to exit(), control will transfer to the 	*/
/* label ___lib_prog_term.  Currently, the ___lib_prog_term label is 	*/
/* defined at the end of the reset vector as an IDLE instruction.    	*/
/* If your application needs to perform some operation AFTER the C   	*/
/* program has finished executing, remove the ___lib_prog_term label 	*/
/* from the runtime header, and place it at the beginning of your    	*/
/* code.							     	*/


/**************************************************************************
New file created June 2001.

The run-time model states that i0 can't be used in the run-time libs.
Use i2 for interrupt handling instead.

**************************************************************************/

#define KERNEL_UART_ISR  0x9000
#define KERNEL_CODEC_ISR 0x9001
#define KERNEL_SWI3_ISR  0x9002

#define __ADSP21065L__
#undef  __ADSP21020__

#include <ezkit/sig_glob.h>

#define	INT(irp)	\
	BIT CLR MODE1 0x1000;				/*Disable interrupts				*/	\
	JUMP ___z3_int_determiner(DB);	/*jmp to finish setting up		*/	\
	DM(I7,M7)=R0;							/*Save r0 (scratch dreg)		*/	\
	R0=SIGMASK(SIG_##irp);				/*Base of int table				*/

#define RESERVED_INTERRUPT NOP;NOP;NOP;NOP

GLOBAL			___lib_prog_term;		/* Termination address				*/
GLOBAL			__done_execution;
EXTERN			___lib_setup_c;
EXTERN			___lib_int_table;
EXTERN         _main;


SEGMENT/PM	    	seg_rth;				/* Runtime header segment			*/

			RESERVED_INTERRUPT;

___lib_RSTI:	 	NOP;					/* Not really executed				*/
			JUMP ___lib_start;
			NOP;
			NOP;

#ifdef __ADSP21160__
___lib_IICDI:           INT(IICDI) ;    /* Access to illegal IOP space */
#else
			RESERVED_INTERRUPT;
#endif

___lib_SOVFI:		INT(SOVF);			/* status/loop/PC stack overflow	*/
___lib_TMZHI:		INT(TMZ0);			/* high priority timer 				*/
___lib_VIRPTI:		INT(VIRPTI);		/* external interrupts 				*/
___lib_IRQ2I:		INT(IRQ2);
___lib_IRQ1I:		INT(IRQ1);

// IRQ0
// This vector is used for the UART.
// It is written during power-on and protected from over-writing
//    by rewriting it after writing data to memory (so this declaration
//    is redundant, but a good reminder).
// Over-writing this vector will stop the kernel.
// The user may over-write it from his/her code - but will loose
//    the capability to communicate over the RS-232 interface.
// IRQ0, IRPTL bit 8, Vector 0x20
___lib_IRQ0I:
	JUMP KERNEL_UART_ISR;	RTI;	NOP;	RTI;
	
			RESERVED_INTERRUPT;
			
___lib_SPR0I:		INT(SPR0I);			/* serial port DMA channel interrupts	*/
___lib_SPR1I:		INT(SPR1I);
___lib_SPT0I:		INT(SPT0I);

// If you wish to use the kernel's codec services, do not write
//   over the following vector
___lib_SPT1I:		
   JUMP KERNEL_CODEC_ISR;	RTI;	RTI;	RTI;
   
#ifndef __ADSP21160__
#ifdef __ADSP21065L__
			RESERVED_INTERRUPT;
			RESERVED_INTERRUPT;
#else
___lib_LP2I:            INT(LP2I);      /* link port DMA channel
interrupts */
___lib_LP3I:            INT(LP3I);
#endif
#else
___lib_LP0I:            INT(LP0I);      /* link port DMA channel 4 */
___lib_LP1I:            INT(LP1I);      /* link port DMA channel 5 */
___lib_LP2I:            INT(LP2I);      /* link port DMA channel
interrupts */
___lib_LP3I:            INT(LP3I);
___lib_LP4I:            INT(LP4I);      /* link port DMA channel 8 */
___lib_LP5I:            INT(LP5I);      /* link port DMA channel 9 */
#endif
___lib_EP0I:		INT(EP0I);			/* ext port DMA channel interrupts	*/
___lib_EP1I:		INT(EP1I);
#ifndef __ADSP21065L__
___lib_EP2I:		INT(EP2I);
___lib_EP3I:		INT(EP3I);
___lib_LSRQ:		INT(LSRQ);			/* link service request 			*/
#else
			RESERVED_INTERRUPT;
			RESERVED_INTERRUPT;
			RESERVED_INTERRUPT;
#endif
___lib_CB7I:		INT(CB7);			/* circular buffer #7 overflow 	*/
___lib_CB15I:		INT(CB15);			/* circular buffer #15 overflow	*/
___lib_TMZLI:		INT(TMZ);			/* low priority timer 				*/
___lib_FIXI:		INT(FIX);			/* fixed point overflow 			*/
___lib_FLTOI:		INT(FLTO);			/* floating point overflow 		*/
___lib_FLTUI:		INT(FLTU);			/* floating point underflow 		*/
___lib_FLTII:		INT(FLTI);			/* floating point invalid 			*/
___lib_SFT0I:		INT(USR0);			/* user interrupts 0..3 			*/
___lib_SFT1I:		INT(USR1);
___lib_SFT2I:		INT(USR2);

// If you wish to use the kernel's host output services, do not write
//   over the following vector
___lib_SFT3I: 
	JUMP KERNEL_SWI3_ISR;	RTI;	RTI;	RTI;

___z3_int_determiner:	
			DM(I7,M7)=R1;					
			R1=I2;
			DM(I7,M7)=R1;					/* Save I2 (scratch reg)			*/
			I2=R0;
			DM(I7,M7)=I13;					/* Save I13 (scratch reg)			*/
			I13=DM(5,I2);					/* get disp to jump to				*/
			JUMP (M13, I13) (DB);		/* Jump to dispatcher 				*/
			BIT SET MODE2 0x80000;		/* Freeze cache						*/
			I13=DM(2,I2);					/* rd handler addr (base+2)		*/

/* Note:  It's okay to use PM in getting the above values b'cse z3 has a
*/
/* linear memory. Therefore dm and pm are the same and we can use
either.*/

___lib_start:		
			CALL ___lib_setup_c;			/* Setup C runtime model			*/
#ifdef MAIN_RTS
			CJUMP _main (DB);				/* Begin C program					*/
			DM(I7,M7)=R2;
			DM(I7,M7)=PC;
#else
			JUMP _main;						/* Begin C program					*/
#endif

/* Setting the __done_execution flag indicates that this processor is	*/
/* finished executing, for the benefit of anyone who may be watching.	*/

___lib_prog_term:	PM(__done_execution)=PC;
			IDLE;
			JUMP ___lib_prog_term;		/* Stay put 							*/

VAR __done_execution = 0;

ENDSEG;







		
This message was sent using the Comp.DSP web interface on
www.DSPRelated.com