This is the mail archive of the ecos-devel@sources.redhat.com mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Error: No rule to make target


Hello guys!
I need help!
I've written a new driver for AC97 Codec for a PXA255 Board. I read the Reference Guide and I made all the necessary steps to make it work with the configurator but I receive always the same error:


make[1]: *** No rule to make target `src/sound_AC97.o.d', needed by `libextras.a.stamp'. Stop.
make -r -C devs/sound/arm/xscale/unipdpxa/v2_0 build
make: *** [build] Error 2
make[1]: Entering directory `/ecos-c/Cygwin/opt/ecos/sound-unipdpxa_build/devs/sound/arm/xscale/unipdpxa/v2_0'
make[1]: Leaving directory `/ecos-c/Cygwin/opt/ecos/sound-unipdpxa_build/devs/sound/arm/xscale/unipdpxa/v2_0'
make: Leaving directory `/ecos-c/Cygwin/opt/ecos/sound-unipdpxa_build'


Nobody can help me? Probably I made a stupid error but I can't recognize it.

I past my files below.
Thank's you all
Andrea

My CDL file is:
-------------------------------------------------------------------------------------------------------------
cdl_package CYGPKG_DEVS_SOUND_ARM_XSCALE_UNIPDPXA {
display  "Sound driver for UNIPDPXA"
 include_dir cyg/io

active_if     CYGPKG_HAL_ARM_XSCALE_UNIPDPXA
   requires      CYGPKG_ERROR
  requires CYGPKG_IO
requires CYGPKG_HAL_ARM_XSCALE_UNIPDPXA

 description "Sound driver for the UNIPDPXA"
compile  -library=libextras.a sound_AC97.c

cdl_component CYGPKG_DEVS_SOUND_ARM_XSCALE_UNIPDPXA_OPTIONS {
 display "Platform Init"
 flavor none
 no_define

cdl_option CYGNUM_HAL_INIT_SOUND {
display "Driver AC97"
flavor bool
default_value 1
description "Sound driver, supporto per periferica AC97"
define -file system.h CYGINT_IO_SOUND
}
cdl_option CYGDAT_DEVS_SOUND_ARM_XSCALE_UNIPDPXA_DEVTAB_BASENAME {
display "Device name for the sound driver"
flavor data
default_value {"\"/dev/sound\""}
description " This option specifies the name of the sound device"
define -file system.h CYGDAT_DEVS_SOUND_ARM_XSCALE_UNIPDPXA_DEVTAB_BASENAME
}
}
}
-------------------------------------------------------------------------------------------------------------


My C file is:
-------------------------------------------------------------------------------------------------------------
//#include <cyg/hal/hal_intr.h> // builds without?
//#include <pkgconf/devs_sound_arm_xscale_unipdpxa.h>
#include <pkgconf/system.h>
#include <pkgconf/io_serial.h>
#include <pkgconf/io.h>
#include <cyg/hal/hal_cache.h>
#include <cyg/io/io.h>
#include <cyg/hal/hal_intr.h>
#include <cyg/io/devtab.h>
#include <cyg/io/serial.h>
#include <cyg/infra/diag.h>
#include <cyg/infra/cyg_ass.h>
#include <cyg/hal/hal_io.h>
#include <cyg/hal/var_io.h>
#include <cyg/io/sound.h>
#include <cyg/io/aclinkcontrol.h>
#include <cyg/io/ac97.h>
#include "ucb1400.h"

static ac97_channel sound_channel;

static cyg_interrupt    ssp_interrupt;
static cyg_handle_t     ssp_int_handle;

///////////////////////////////////////////////////////////////////////////////
//
// Channel interface
//
///////////////////////////////////////////////////////////////////////////////

cyg_bool debug_desc_mode = true;

/* TODO:
   1.  Fa correttamente l'ultima play o no?
   2.  Perch�vi sono degli errori di bus di tanto in tanto?

*/

// Public functions:
short int init_AcLink();
short int AC97_ColdReset();
short int AC97_read(char Offset, unsigned short int * Data);
short int AC97_write(char Offset, unsigned short int Data);
//----------------------------------------------------------------------------------------------------------------

// Private funcions:
short int private_init_gpio();
static cyg_uint32 desc_load_fragment(cyg_uint32 frag_num, cyg_bool enable_irq);
static cyg_uint32 desc_play_fragment(cyg_uint32 frag_num, cyg_bool enable_irq);
static cyg_uint32 desc_unload_fragment(cyg_uint32 frag_num, cyg_bool enable_irq);
static cyg_uint32 desc_record_fragment(cyg_uint32 frag_num, cyg_bool enable_irq);
static Cyg_ErrNo sound_set_config(cyg_uint32 key, const void *buffer, cyg_uint32 *len);
static void audio_power_off(void);


//----------------------------------------------------------------------------------------------------------------

short int private_init_gpio() {
short int retval=false;
// Transition to active. Log this client and perform the activation
   if (ac97.GpioIsConfigured)
       return true;
   SET(PXA255_GPDR0, 0XC0000000);   // Set up of input/output direction
   SET(PXA255_GAFR0_U, 0xA5000000); // Set up of the Alternate Function
       AC97_ColdReset();
do {
 hal_delay_us(100000);
} while(!TEST(PXA255_GSR, AC97GSR_CODEC_READY_BIT));
ac97.GpioIsConfigured = true;
retval = true;
return(retval);
}

short int AC97_ColdReset()
{
SET(PXA255_GCR,AC97GCR_ColdReset);
}

short int init_AcLink()
{
   ac97.GpioIsConfigured = false;
   return (private_init_gpio());
}

short int AC97_read(char Offset, unsigned short int * Data)
{
SET(PXA255_GSR, AC97GSR_SDONE);
CLEAR(PXA255_GSR, AC97GSR_READ_COMPLETION_STATUS);
// lock the channel:
while(TEST(PXA255_CAR,AC97CAR_CAIP)); // the test returns true if
volatile unsigned long *DerivedAddr; // Accessing CODEC Registers
DerivedAddr = (unsigned long *) ((unsigned char *) PXA255_AC97_PRIM_AUDIO_BASE + (Offset << 1)) ;
*Data = (volatile unsigned short int) *DerivedAddr ; // dummy read
while(TEST(PXA255_GSR, AC97GSR_SDONE)==CLEAR_BIT); // check for sdone bit, if set proceed
SET(PXA255_GSR, AC97GSR_SDONE); // clearing the sdone bit
*Data = (volatile unsigned short int) *DerivedAddr ; // actual read
while(TEST(PXA255_GSR, AC97GSR_SDONE)==CLEAR_BIT); // check for sdone bit, if set proceed
if(TEST(PXA255_GSR, AC97GSR_READ_COMPLETION_STATUS)) // if sdone bit were not set we have an
{ CLEAR(PXA255_GSR, AC97GSR_READ_COMPLETION_STATUS); // error, TIMED_OUT_DATA.
return(ERR_DATA_TIMED_OUT);
}
else
{
return(SUCCESS);
}
}


short int AC97_write(char Offset, unsigned short int Data)
{
volatile unsigned long *DerivedAddr;
while(TEST(PXA255_CAR,AC97CAR_CAIP)); // waiting the end of the old cycle before begin
DerivedAddr = (unsigned long *) ((unsigned char *) PXA255_AC97_PRIM_AUDIO_BASE + (Offset << 1)) ;
SET(PXA255_GSR, AC97GSR_CDONE); // just to be sure
(volatile unsigned short int) *DerivedAddr = Data; // write data
while(TEST(PXA255_GSR, AC97GSR_CDONE)==CLEAR_BIT);
SET(PXA255_GSR, AC97GSR_CDONE);
return(SUCCESS);
}


static int
ssp_isr(cyg_vector_t vector, cyg_addrword_t data, HAL_SavedRegisters *regs)
{
cyg_drv_interrupt_acknowledge(CYGNUM_HAL_INTERRUPT_DMA);
cyg_interrupt_disable();
if (TEST(PXA255_DINT, PXA255_DINT_CHLINTR7)) {
if(TEST(PXA255_DCSR7, PXA255_DCSR_ENDINTR)) {
SET(PXA255_DCSR7, PXA255_DCSR_ENDINTR);
sound_channel.available_data += sound_channel.input.fragment_len[sound_channel.recorded_frag];
sound_channel.input.fragment_len[sound_channel.recorded_frag] = 0;
//if(sound_channel.read_sem != NULL) {
cyg_semaphore_post(sound_channel.read_sem);
//}


}
}
if (TEST(PXA255_DINT, PXA255_DINT_CHLINTR3)) {
if(TEST(PXA255_DCSR3, PXA255_DCSR_ENDINTR)) {
SET(PXA255_DCSR3, PXA255_DCSR_ENDINTR);
sound_channel.recorded_frag = sound_channel.input.select_fragment;
sound_channel.input.select_fragment = ++sound_channel.input.select_fragment % sound_channel.input.frag_number;
if(sound_channel.recording_state == CHANNEL_STATE_SUSPENDED) {
desc_unload_fragment(sound_channel.recorded_frag, false);
//sound_channel.input.select_fragment = ++sound_channel.input.select_fragment % sound_channel.input.frag_number;
sound_channel.input.rotation_count++;


}
else if(sound_channel.input.rotation_count < sound_channel.input.rotation_number - 1) {
sound_channel.input.rotation_count++;
desc_unload_fragment(sound_channel.recorded_frag, true); //true Modified to allow partial reading
desc_record_fragment(sound_channel.input.select_fragment, true);


  }
  else {
   desc_unload_fragment(sound_channel.recorded_frag, true);//true
   }
         }
}


if (TEST(PXA255_DINT, PXA255_DINT_CHLINTR4)) {
if(TEST(PXA255_DCSR4, PXA255_DCSR_ENDINTR)) {
SET(PXA255_DCSR4, PXA255_DCSR_ENDINTR);
sound_channel.output.select_fragment = ++sound_channel.output.select_fragment % sound_channel.output.frag_number;
desc_load_fragment(1, false);
desc_play_fragment(0, true);


}
}
if(TEST(PXA255_DINT, PXA255_DINT_CHLINTR2)) {
if(TEST(PXA255_DCSR2, PXA255_DCSR_ENDINTR)) {
SET(PXA255_DCSR2, PXA255_DCSR_ENDINTR);
sound_channel.loaded_frag = sound_channel.output.select_fragment;
sound_channel.output.select_fragment = ++sound_channel.output.select_fragment % sound_channel.output.frag_number;


if(sound_channel.output.rotation_count < sound_channel.output.rotation_number - 2) {
desc_play_fragment(sound_channel.loaded_frag, true);
desc_load_fragment(sound_channel.output.select_fragment, false);
sound_channel.output.rotation_count++;
}
else {
desc_play_fragment(sound_channel.loaded_frag, false);
}





}


}
cyg_interrupt_enable();
return CYG_ISR_HANDLED;
}

static void
ssp_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data )
{

}

pxa_dma_desc* alloc_dma_desc(cyg_uint32 num_desc) {
cyg_uint8* pointer = (cyg_uint8*)malloc(DMA_DESC_SIZE * num_desc + 15);
pointer += (volatile cyg_uint32)pointer & 0xF ? 0x10 - ((volatile cyg_uint32)pointer & 0xF) : 0;
return (pxa_dma_desc*)pointer;
}


static void init_dma() {
SET(PXA255_DRCMR12, PXA255_DRCMR_CHLNUM_2);
SET(PXA255_DRCMR12,    PXA255_DRCMR_MAPVLD);
cyg_drv_interrupt_create( CYGNUM_HAL_INTERRUPT_DMA,
   69,
   0,
   (cyg_ISR_t*)ssp_isr,
   (cyg_DSR_t*)ssp_dsr,
   &ssp_int_handle,
   &ssp_interrupt );
   cyg_drv_interrupt_attach( ssp_int_handle );
   cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_DMA);
}


static void channel_init() {
init_dma();
int i;
if(!sound_channel.input.initializated) {
if(sound_channel.ch_initializated) {
for (i=0; i<sound_channel.input.frag_number;i++){
free(sound_channel.input.fragment[i]);
}
free(sound_channel.input.fragment);
free(sound_channel.input.fragment_len);
free(sound_channel.input.fragment_offset);
free(sound_channel.input.phys_transfer_start_address);
}
sound_channel.input.fragment = (cyg_uint32**)malloc(sound_channel.input.frag_number * sizeof(cyg_uint32*));
for (i=0; i<sound_channel.input.frag_number;i++){
sound_channel.input.fragment[i] = (cyg_uint32*)malloc(sound_channel.input.frag_size);
}
sound_channel.input.fragment_len = (cyg_uint32*)malloc(sound_channel.input.frag_number * sizeof(cyg_uint32));
sound_channel.input.fragment_offset = (cyg_uint32*)malloc(sound_channel.input.frag_number * sizeof(cyg_uint32));
sound_channel.input.phys_transfer_start_address = (cyg_uint32*)malloc(sound_channel.input.frag_number * sizeof(cyg_uint32));
}
if(!sound_channel.output.initializated) {
if(sound_channel.ch_initializated) {
for (i=0; i<sound_channel.output.frag_number;i++){
free(sound_channel.output.fragment[i]);
}
free(sound_channel.output.fragment);
free(sound_channel.output.fragment_len);
free(sound_channel.output.fragment_offset);
free(sound_channel.output.phys_transfer_start_address);
}
sound_channel.output.fragment = (cyg_uint32**)malloc(sound_channel.output.frag_number * sizeof(cyg_uint32*));
for (i=0; i<sound_channel.output.frag_number;i++){
sound_channel.output.fragment[i] = (cyg_uint32*)malloc(sound_channel.output.frag_size);
}
sound_channel.output.fragment_len = (cyg_uint32*)malloc(sound_channel.output.frag_number * sizeof(cyg_uint32));
sound_channel.output.fragment_offset = (cyg_uint32*)malloc(sound_channel.output.frag_number * sizeof(cyg_uint32));
sound_channel.output.phys_transfer_start_address = (cyg_uint32*)malloc(sound_channel.output.frag_number * sizeof(cyg_uint32));
}
if(!sound_channel.input.initializated) {
if(sound_channel.ch_initializated) {
free(sound_channel.input.mem2mem);
free(sound_channel.input.mem2per);
}
sound_channel.input.mem2mem = alloc_dma_desc(sound_channel.input.frag_size / PXA255_DMA_TRANSFER_SIZE + 1);
sound_channel.input.mem2per = alloc_dma_desc(sound_channel.input.frag_size / PXA255_DMA_TRANSFER_SIZE + 1);
sound_channel.input.initializated = true;
}
if(!sound_channel.output.initializated) {
if(sound_channel.ch_initializated) {
free(sound_channel.output.mem2mem);
free(sound_channel.output.mem2per);
}
sound_channel.output.mem2mem = alloc_dma_desc(sound_channel.output.frag_size / PXA255_DMA_TRANSFER_SIZE + 1);
sound_channel.output.mem2per = alloc_dma_desc(sound_channel.output.frag_size / PXA255_DMA_TRANSFER_SIZE + 1);
sound_channel.output.initializated = true;
}


sound_channel.ch_initializated = true;
}

static Cyg_ErrNo sound_get_config(cyg_uint32 key, void *buffer, cyg_uint32 *len) {
CYG_CHECK_DATA_PTRC( buffer );
switch ( key ) {


default :
    return -EDEVNOSUPP;
   }
   return ENOERR;
}

static cyg_bool private_test_sample_rate(cyg_uint32 sample_rate) {
switch (sample_rate) {
 case CYG_IO_SET_SAMPLE_RATE_8000 :
     return true;
   case CYG_IO_SET_SAMPLE_RATE_11025 :
       return true;
       case CYG_IO_SET_SAMPLE_RATE_12000 :
           return true;
       case CYG_IO_SET_SAMPLE_RATE_16000 :
           return true;
       case CYG_IO_SET_SAMPLE_RATE_22050 :
           return true;
       case CYG_IO_SET_SAMPLE_RATE_24000 :
           return true;
       case CYG_IO_SET_SAMPLE_RATE_32000 :
           return true;
       case CYG_IO_SET_SAMPLE_RATE_44100 :
           return true;
       case CYG_IO_SET_SAMPLE_RATE_48000 :
           return true;
       default:
           return false;
 }
}


#define PRIVATE_TEST_VOLUME(volume) ((volume >= 0)&&(volume <= 100))




void private_set_ac97(void) {

AC97_write(MASTER_VOLUME, (MASTER_MUTE_MASK & sound_channel.vol_output.mute) | (63-((sound_channel.vol_output.volume_left) * 63) / 100)<<8 | 63-((sound_channel.vol_output.volume_right) * 63) / 100);
hal_delay_us(100000);


AC97_write(RECORD_GAIN, (MASTER_RECORD_MUTE_MASK & sound_channel.vol_input.mute) | (sound_channel.vol_input.volume_left * 15 / 100)<<8 | sound_channel.vol_input.volume_right * 15 / 100);
hal_delay_us(100000);


AC97_write(AUDIO_ADC_RATE, sound_channel.adc_rate);
hal_delay_us(100000);

AC97_write(AUDIO_DAC_RATE, sound_channel.dac_rate);
hal_delay_us(100000);

AC97_write(RECORD_SELECT, (LEFT_RECORD_SOURCE_MASK & (sound_channel.input_from_line_in<<10))|(RIGHT_RECORD_SOURCE_MASK & (sound_channel.input_from_line_in<<2)));
hal_delay_us(100000);


if (sound_channel.input_from_line_in){
 SET(PXA255_DRCMR11, PXA255_DRCMR_CHLNUM_3);      //line-in
 SET(PXA255_DRCMR11,    PXA255_DRCMR_MAPVLD);
}
else {
 SET(PXA255_DRCMR8, PXA255_DRCMR_CHLNUM_3);      //mic-in
 SET(PXA255_DRCMR8,    PXA255_DRCMR_MAPVLD);
}
}

static void audio_power_off(void){

}


static Cyg_ErrNo sound_set_config(cyg_uint32 key, const void* buffer, cyg_uint32* len) {


switch ( key ) {
case CYG_IO_SET_CONFIG_ENCODING :
if ( *len != sizeof(cyg_uint32) )
return -EINVAL;
return -EDEVNOSUPP;
case CYG_IO_SET_CONFIG_SAM_RATE_ADC :
if ( *len != sizeof(cyg_uint32) )
return -EINVAL;
if(private_test_sample_rate(*(cyg_uint32*)buffer))
sound_channel.adc_rate = *(cyg_uint32*)buffer;
else return -EINVAL;
break;
case CYG_IO_SET_CONFIG_SAM_RATE_DAC :
if ( *len != sizeof(cyg_uint32) )
return -EINVAL;
if(private_test_sample_rate(*(cyg_uint32*)buffer))
sound_channel.dac_rate = *(cyg_uint32*)buffer;
else return -EINVAL;
break;
case CYG_IO_SET_CONFIG_OUT_MASTER_GAIN :
if ( *len != sizeof(cyg_uint32) )
return -EINVAL;
if(PRIVATE_TEST_VOLUME(*(cyg_uint32*)buffer)) {
sound_channel.vol_output.volume_left = *(cyg_uint16*)buffer;
sound_channel.vol_output.volume_right = *(cyg_uint16*)buffer; }
break;
case CYG_IO_SET_CONFIG_OUT_LEFT_GAIN :
if ( *len != sizeof(cyg_uint32) )
return -EINVAL;
if(PRIVATE_TEST_VOLUME(*(cyg_uint32*)buffer)) {
sound_channel.vol_output.volume_left = (cyg_uint16)*(cyg_uint32*)buffer; }
break;
case CYG_IO_SET_CONFIG_OUT_RIGHT_GAIN :
if ( *len != sizeof(cyg_uint32) )
return -EINVAL;
if(PRIVATE_TEST_VOLUME(*(cyg_uint32*)buffer)) {
sound_channel.vol_output.volume_right = (cyg_uint16)*(cyg_uint32*)buffer; }
break;
case CYG_IO_SET_CONFIG_IN_MASTER_GAIN :
if ( *len != sizeof(cyg_uint32) )
return -EINVAL;
if(PRIVATE_TEST_VOLUME(*(cyg_uint32*)buffer)) {
sound_channel.vol_input.volume_left = (cyg_uint16)*(cyg_uint16*)buffer;
sound_channel.vol_input.volume_right = (cyg_uint16)*(cyg_uint16*)buffer; }
break;
case CYG_IO_SET_CONFIG_IN_LEFT_GAIN :
if ( *len != sizeof(cyg_uint32) )
return -EINVAL;
if(PRIVATE_TEST_VOLUME(*(cyg_uint32*)buffer)) {
sound_channel.vol_input.volume_left = (cyg_uint16)*(cyg_uint32*)buffer; }
break;
case CYG_IO_SET_CONFIG_IN_RIGHT_GAIN :
if ( *len != sizeof(cyg_uint32) )
return -EINVAL;
if(PRIVATE_TEST_VOLUME(*(cyg_uint32*)buffer)) {
sound_channel.vol_input.volume_right = (cyg_uint16)*(cyg_uint32*)buffer; }
break;
case CYG_IO_SET_CONFIG_FLUSH :
break;
case CYG_IO_SET_CONFIG_CLOSE :
audio_power_off();
break;
/* case CYG_IO_SET_CONFIG_PAUSE :
sound_channel.pause = true;
break;
case CYG_IO_SET_CONFIG_RESUME :
sound_channel.pause = false;
break;*/
case CYG_IO_SET_CONFIG_OUT_MUTE :
sound_channel.vol_output.mute = true;
break;
case CYG_IO_SET_CONFIG_IN_MUTE :
sound_channel.vol_input.mute = true;
break;
case CYG_IO_SET_CONFIG_SELECT_LINE_IN :
sound_channel.input_from_line_in = true;
break;
case CYG_IO_SET_CONFIG_SELECT_MICROPHONE :
sound_channel.input_from_line_in = false;
break;
case CYG_IO_SET_CONFIG_PRECISION :
if ( *len != sizeof(cyg_uint32) )
return -EINVAL;
sound_channel.stereo = (0x2 & *(cyg_uint32*)buffer);
sound_channel.sample_16bits = (0x1 & *(cyg_uint32*)buffer);
break;
case CYG_IO_SET_CONFIG_FRAG_NUMBER_READ :
if ( *len != sizeof(cyg_uint32) )
return -EINVAL;
if(sound_channel.recording_state == CHANNEL_STATE_IDLE) {
sound_channel.input.frag_number = *(cyg_uint32*)buffer;
}
else return -EDEVNOSUPP;
break;
case CYG_IO_SET_CONFIG_FRAG_NUMBER_WRITE :
if ( *len != sizeof(cyg_uint32) )
return -EINVAL;
if(sound_channel.playing_state == CHANNEL_STATE_IDLE) {
sound_channel.output.frag_number = *(cyg_uint32*)buffer;
}
else return -EDEVNOSUPP;
break;
case CYG_IO_SET_CONFIG_FRAG_SIZE_WRITE :
if ( *len != sizeof(cyg_uint32) )
return -EINVAL;
if(sound_channel.playing_state == CHANNEL_STATE_IDLE) {
sound_channel.output.frag_size = *(cyg_uint32*)buffer;
}
else return -EDEVNOSUPP;
break;
case CYG_IO_SET_CONFIG_FRAG_SIZE_READ :
if ( *len != sizeof(cyg_uint32) )
return -EINVAL;
if(sound_channel.recording_state == CHANNEL_STATE_IDLE) {
sound_channel.input.frag_size = *(cyg_uint32*)buffer;
}
else return -EDEVNOSUPP;
break;
default :
return -EDEVNOSUPP;
}
private_set_ac97();
return ENOERR;
}



static inline void sound_init(void){


//Basic Outline:
// configue the GPIO registers

// Set hardcoded values like variable rate audio
// Set the BCR values (for sandgate)
// Set key register values to the values from the shadow registers
// Set volume
// Set record select
// Set EQ values (bass, treble, and mode)
// Clear Audio Mute (output & input)

#ifdef CYGINT_IO_SOUND

if (init_AcLink()!=SUCCESS)
 return ;


//Force VRA (variable rate audio) to be on
AC97_write(EXTENDED_AUDIO_CTRL, ENABLE_VRA_MASK); // Enable Variable Rate Audio
hal_delay_us(100000);
sound_channel.input_from_line_in = true;


//Set the record gain value
sound_channel.vol_input.volume_left = 0;
sound_channel.vol_input.volume_right = 0;

sound_channel.vol_output.volume_left = 100;
sound_channel.vol_output.volume_right = 100;

sound_channel.dac_rate=48000;
sound_channel.adc_rate=48000;

sound_channel.vol_input.mute = false;
sound_channel.vol_output.mute = false;

sound_channel.recording_state = CHANNEL_STATE_IDLE;
sound_channel.playing_state = CHANNEL_STATE_IDLE;

sound_channel.stereo = true;
sound_channel.sample_16bits = true;

sound_channel.ch_initializated = false;
sound_channel.input.initializated = false;
sound_channel.output.initializated = false;

sound_channel.input.frag_number = 2;
sound_channel.output.frag_number = 2;

sound_channel.input.frag_size = PXA255_DMA_TRANSFER_SIZE * 200;
sound_channel.output.frag_size = PXA255_DMA_TRANSFER_SIZE * 4;

private_set_ac97();

channel_init();

#endif
}



static cyg_uint32 desc_play_fragment(cyg_uint32 frag_num, cyg_bool enable_irq) {
while (!TEST(PXA255_DCSR2, PXA255_DCSR_STOPSTATE));
HAL_DCACHE_SYNC();
HAL_DCACHE_INVALIDATE_ALL();
HAL_DCACHE_DISABLE();
sound_channel.output.fragment_offset[frag_num] = 0;
int limit = sound_channel.output.fragment_len[frag_num] > sound_channel.output.frag_size ? sound_channel.output.frag_size : sound_channel.output.fragment_len[frag_num];
cyg_uint32 desc_num = limit / PXA255_DMA_TRANSFER_SIZE;
desc_num += limit % PXA255_DMA_TRANSFER_SIZE ? 1 : 0;
cyg_uint32 desc_index = 0;
for(desc_index = 0; desc_index < desc_num; desc_index++) {
sound_channel.output.mem2per[desc_index].dsadr = CYGARC_PHYSICAL_ADDRESS(sound_channel.output.fragment[frag_num] + sound_channel.output.fragment_offset[frag_num]);
sound_channel.output.mem2per[desc_index].dtadr = (cyg_uint32) PXA255_PCDR;
sound_channel.output.mem2per[desc_index].ddadr = CYGARC_PHYSICAL_ADDRESS(&sound_channel.output.mem2per[desc_index+1]);
sound_channel.output.mem2per[desc_index].dcmd = PXA255_DCMD_INCSRCADDR | PXA255_DCMD_FLOWTRG | PXA255_DCMD_SIZE_32 | PXA255_DCMD_WIDTH_WORD;
if (limit - sound_channel.output.fragment_offset[frag_num] >= PXA255_DMA_TRANSFER_SIZE) {
sound_channel.output.mem2per[desc_index].dcmd |= PXA255_DMA_TRANSFER_SIZE;
sound_channel.output.fragment_offset[frag_num] += PXA255_DMA_TRANSFER_SIZE;
}
else {
sound_channel.output.mem2per[desc_index].dcmd |= limit - sound_channel.output.fragment_offset[frag_num];
}
}
desc_index--;
if(enable_irq) {
sound_channel.output.mem2per[desc_index].dcmd |= PXA255_DCMD_ENDIRQEN;
}
sound_channel.output.mem2per[desc_index].ddadr |= PXA255_DDADR_STOP;
*PXA255_DDADR2 = CYGARC_PHYSICAL_ADDRESS(sound_channel.output.mem2per);
sound_channel.output.fragment_len[frag_num] = 0;
sound_channel.output.fragment_offset[frag_num] = 0;
SET(PXA255_DCSR2, PXA255_DCSR_RUN);
HAL_DCACHE_ENABLE();
return limit;
}


/*
WORKING 14.38 01/20/05
*/


static cyg_uint32 desc_load_fragment(cyg_uint32 frag_num, cyg_bool enable_irq) {
while (!TEST(PXA255_DCSR4, PXA255_DCSR_STOPSTATE));
HAL_DCACHE_SYNC();
HAL_DCACHE_INVALIDATE_ALL();
HAL_DCACHE_DISABLE();
int limit = sound_channel.output.sample.length - sound_channel.output.sample.offset > sound_channel.output.frag_size ? sound_channel.output.frag_size : sound_channel.output.sample.length - sound_channel.output.sample.offset;
cyg_uint32 desc_num = limit / PXA255_DMA_TRANSFER_SIZE;
desc_num += limit % PXA255_DMA_TRANSFER_SIZE ? 1 : 0;
sound_channel.output.fragment_len[frag_num] = 0;
cyg_uint32 desc_index = 0;
sound_channel.output.fragment_offset[frag_num] = 0;
for(desc_index = 0; desc_index < desc_num; desc_index++) {
sound_channel.output.mem2mem[desc_index].dsadr = CYGARC_PHYSICAL_ADDRESS(sound_channel.output.sample.buffer + sound_channel.output.sample.offset + sound_channel.output.fragment_offset[frag_num]);
sound_channel.output.mem2mem[desc_index].dtadr = CYGARC_PHYSICAL_ADDRESS(sound_channel.output.fragment[frag_num] + sound_channel.output.fragment_offset[frag_num]);
sound_channel.output.mem2mem[desc_index].ddadr = CYGARC_PHYSICAL_ADDRESS(&sound_channel.output.mem2mem[desc_index+1]);
sound_channel.output.mem2mem[desc_index].dcmd = PXA255_DCMD_INCSRCADDR | PXA255_DCMD_INCTRGADDR | PXA255_DCMD_SIZE_32 | PXA255_DCMD_WIDTH_WORD;
if (limit - sound_channel.output.fragment_offset[frag_num] >= PXA255_DMA_TRANSFER_SIZE) {
sound_channel.output.mem2mem[desc_index].dcmd |= PXA255_DMA_TRANSFER_SIZE;
sound_channel.output.fragment_offset[frag_num] += PXA255_DMA_TRANSFER_SIZE;
}
else {
sound_channel.output.mem2mem[desc_index].dcmd |= limit - sound_channel.output.fragment_offset[frag_num];
}
}


desc_index--;
if(enable_irq) {
 sound_channel.output.mem2mem[desc_index].dcmd |= PXA255_DCMD_ENDIRQEN;
}

sound_channel.output.mem2mem[desc_index].ddadr |= PXA255_DDADR_STOP;
*PXA255_DDADR4 = CYGARC_PHYSICAL_ADDRESS(sound_channel.output.mem2mem);
sound_channel.output.fragment_len[frag_num] = limit;
sound_channel.output.sample.offset += limit;
sound_channel.output.fragment_offset[frag_num] = 0;
SET(PXA255_DCSR4, PXA255_DCSR_RUN);
HAL_DCACHE_ENABLE();
return limit;
}



static Cyg_ErrNo sound_write(const void *buffer, cyg_uint32 *len) {

// inserire controlli sulla precisione e stereo
// e gestione dei buffer ottimizzata
//if(sound_channel.playing_state != CHANNEL_STATE_IDLE)
// return -EBUSY;
sound_channel.playing_state = CHANNEL_STATE_PLAYING;
sound_channel.output.sample.buffer = (cyg_uint32*)buffer;
sound_channel.output.sample.length = *len;
sound_channel.output.sample.offset = 0;

sound_channel.output.rotation_number = sound_channel.output.sample.length / sound_channel.output.frag_size;
sound_channel.output.rotation_number += sound_channel.output.sample.length % sound_channel.output.frag_size ? 1 : 0;


sound_channel.output.rotation_count = 0;
sound_channel.output.select_fragment = 0;

/*if(sound_channel.playing_state == CHANNEL_STATE_PLAYING)
 return -EBUSY;
sound_channel.playing_state = CHANNEL_STATE_PLAYING;*/

cyg_interrupt_disable();
desc_load_fragment(sound_channel.output.select_fragment, true);
cyg_interrupt_enable();

   return ENOERR;
}

static cyg_uint32 desc_unload_fragment(cyg_uint32 frag_num, cyg_bool enable_irq) {
while (!TEST(PXA255_DCSR7, PXA255_DCSR_STOPSTATE));
HAL_DCACHE_SYNC();
HAL_DCACHE_INVALIDATE_ALL();
HAL_DCACHE_DISABLE();
int limit = sound_channel.input.sample.length - sound_channel.input.sample.offset > sound_channel.input.fragment_len[frag_num] ? sound_channel.input.fragment_len[frag_num] : sound_channel.input.sample.length - sound_channel.input.sample.offset;


cyg_uint32 desc_num = limit / PXA255_DMA_TRANSFER_SIZE;
desc_num += limit % PXA255_DMA_TRANSFER_SIZE ? 1 : 0;
//sound_channel.input.fragment_len[frag_num] = 0;
cyg_uint32 desc_index = 0;

sound_channel.input.fragment_offset[frag_num] = 0;

for(desc_index = 0; desc_index < desc_num; desc_index++) {

sound_channel.input.mem2mem[desc_index].dtadr = CYGARC_PHYSICAL_ADDRESS(sound_channel.input.sample.buffer + sound_channel.input.sample.offset + sound_channel.input.fragment_offset[frag_num]);

sound_channel.input.mem2mem[desc_index].dsadr = CYGARC_PHYSICAL_ADDRESS(sound_channel.input.fragment[frag_num] + sound_channel.input.fragment_offset[frag_num]);

sound_channel.input.mem2mem[desc_index].ddadr = CYGARC_PHYSICAL_ADDRESS(&sound_channel.input.mem2mem[desc_index+1]);

sound_channel.input.mem2mem[desc_index].dcmd = PXA255_DCMD_INCSRCADDR | PXA255_DCMD_INCTRGADDR | PXA255_DCMD_SIZE_32 | PXA255_DCMD_WIDTH_WORD;

if (limit - sound_channel.input.fragment_offset[frag_num] >= PXA255_DMA_TRANSFER_SIZE) {
sound_channel.input.mem2mem[desc_index].dcmd |= PXA255_DMA_TRANSFER_SIZE;
sound_channel.input.fragment_offset[frag_num] += PXA255_DMA_TRANSFER_SIZE;
}
else {
sound_channel.input.mem2mem[desc_index].dcmd |= limit - sound_channel.input.fragment_offset[frag_num];
}
}


desc_index--;
if(enable_irq) {
 sound_channel.input.mem2mem[desc_index].dcmd |= PXA255_DCMD_ENDIRQEN;
}

sound_channel.input.mem2mem[desc_index].ddadr |= PXA255_DDADR_STOP;
*PXA255_DDADR7 = CYGARC_PHYSICAL_ADDRESS(sound_channel.input.mem2mem);
//sound_channel.input.fragment_len[frag_num] = 0;
sound_channel.input.sample.offset += limit;
sound_channel.input.fragment_offset[frag_num] = 0;
SET(PXA255_DCSR7, PXA255_DCSR_RUN);
HAL_DCACHE_ENABLE();
return limit;
}



static cyg_uint32 desc_record_fragment(cyg_uint32 frag_num, cyg_bool enable_irq) {
while (!TEST(PXA255_DCSR3, PXA255_DCSR_STOPSTATE));
HAL_DCACHE_SYNC();
HAL_DCACHE_INVALIDATE_ALL();
HAL_DCACHE_DISABLE();
sound_channel.input.fragment_len[frag_num] = 0;
sound_channel.input.fragment_offset[frag_num] = 0;


int limit = sound_channel.input.sample.length - sound_channel.input.sample.offset > sound_channel.input.frag_size ? sound_channel.input.frag_size : sound_channel.input.sample.length - sound_channel.input.sample.offset;

cyg_uint32 desc_num = limit / PXA255_DMA_TRANSFER_SIZE;
desc_num += limit % PXA255_DMA_TRANSFER_SIZE ? 1 : 0;
cyg_uint32 desc_index = 0;
for(desc_index = 0; desc_index < desc_num; desc_index++) {
sound_channel.input.mem2per[desc_index].dtadr = CYGARC_PHYSICAL_ADDRESS(sound_channel.input.fragment[frag_num] + sound_channel.input.fragment_offset[frag_num]);
if (sound_channel.input_from_line_in)
sound_channel.input.mem2per[desc_index].dsadr = (cyg_uint32) PXA255_PCDR;
else sound_channel.input.mem2per[desc_index].dsadr = (cyg_uint32) PXA255_MCDR;



sound_channel.input.mem2per[desc_index].ddadr = CYGARC_PHYSICAL_ADDRESS(&sound_channel.input.mem2per[desc_index+1]);


sound_channel.input.mem2per[desc_index].dcmd = PXA255_DCMD_INCTRGADDR | PXA255_DCMD_FLOWSRC | PXA255_DCMD_SIZE_32 | PXA255_DCMD_WIDTH_WORD;
if (limit - sound_channel.input.fragment_offset[frag_num] >= PXA255_DMA_TRANSFER_SIZE) {
sound_channel.input.mem2per[desc_index].dcmd |= PXA255_DMA_TRANSFER_SIZE;
sound_channel.input.fragment_offset[frag_num] += PXA255_DMA_TRANSFER_SIZE;
}
else {
sound_channel.input.mem2per[desc_index].dcmd |= limit - sound_channel.input.fragment_offset[frag_num];
}
}
desc_index--;
if(enable_irq) {
sound_channel.input.mem2per[desc_index].dcmd |= PXA255_DCMD_ENDIRQEN;
}
sound_channel.input.mem2per[desc_index].ddadr |= PXA255_DDADR_STOP;
*PXA255_DDADR3 = CYGARC_PHYSICAL_ADDRESS(sound_channel.input.mem2per);
sound_channel.input.fragment_len[frag_num] = limit;
sound_channel.input.fragment_offset[frag_num] = 0;
SET(PXA255_DCSR3, PXA255_DCSR_RUN);
HAL_DCACHE_ENABLE();
return limit;
}


static Cyg_ErrNo start_sound_read(cyg_uint32 *buffer, cyg_uint32 *len) {
/*
if(sound_channel.recording_state != CHANNEL_STATE_IDLE) {
 return -EBUSY;
 }
*/
sound_channel.recording_state = CHANNEL_STATE_RECORDING;

sound_channel.input.sample.buffer = (cyg_uint32*)buffer;
sound_channel.input.sample.length = *len;
sound_channel.input.sample.offset = 0;

sound_channel.input.rotation_count = 0;
sound_channel.input.select_fragment = 0;

sound_channel.input.rotation_number = sound_channel.input.sample.length / sound_channel.input.frag_size;
sound_channel.input.rotation_number += sound_channel.input.sample.length % sound_channel.input.frag_size ? 1 : 0;
sound_channel.available_data = 0;
sound_channel.read_offset = 0;


 //cyg_interrupt_disable();
desc_record_fragment(sound_channel.input.select_fragment, true);
//cyg_interrupt_enable();

 return ENOERR;
}

static Cyg_ErrNo partial_sound_read(cyg_uint32 *len) {
if((sound_channel.read_sem != NULL)||(sound_channel.recording_state != CHANNEL_STATE_RECORDING)) {
return -EBUSY;
}
cyg_semaphore_init(sound_channel.read_sem, 0);
while(sound_channel.available_data - sound_channel.read_offset < *len) {
cyg_semaphore_wait(sound_channel.read_sem);
}
sound_channel.read_offset += *len;
cyg_semaphore_destroy(sound_channel.read_sem);
return ENOERR;
}


/* Blocking sound read */
static Cyg_ErrNo sound_read(cyg_uint32 *buffer, cyg_uint32 *len) {
   Cyg_ErrNo result = start_sound_read(buffer, len);
   if(result == ENOERR) {
    result = partial_sound_read(len);
   }
   return result;
}

static Cyg_ErrNo pause_playing() {
if(sound_channel.playing_state == CHANNEL_STATE_PLAYING) {
 sound_channel.playing_state = CHANNEL_STATE_SUSPENDED;
 return ENOERR;
}
return -ENOSUPP;
}

static Cyg_ErrNo resume_playing() {
if(sound_channel.playing_state == CHANNEL_STATE_SUSPENDED) {
sound_channel.playing_state = CHANNEL_STATE_PLAYING;
if(sound_channel.output.rotation_count < sound_channel.output.rotation_number - 1) {
desc_load_fragment(sound_channel.output.select_fragment, false);
cyg_uint32 play_frag = sound_channel.output.select_fragment;
sound_channel.output.select_fragment = ++sound_channel.output.select_fragment % sound_channel.output.frag_number;
sound_channel.output.rotation_count++;
desc_play_fragment(play_frag, true);
return CYG_ISR_HANDLED;
}
else {
desc_play_fragment(sound_channel.output.select_fragment, false);
sound_channel.playing_state = CHANNEL_STATE_IDLE;
return CYG_ISR_HANDLED;
}
return ENOERR;
}
return -ENOSUPP;
}



static Cyg_ErrNo pause_recording() { if(sound_channel.recording_state == CHANNEL_STATE_RECORDING) { sound_channel.recording_state = CHANNEL_STATE_SUSPENDED; return ENOERR; } return -ENOSUPP; }

static Cyg_ErrNo resume_recording() {
if(sound_channel.recording_state == CHANNEL_STATE_SUSPENDED) {
 sound_channel.recording_state = CHANNEL_STATE_RECORDING;
 desc_record_fragment(sound_channel.input.select_fragment, true);
 return ENOERR;
}
return -ENOSUPP;
}

static Cyg_ErrNo new_sound_write(const void *buffer, cyg_uint32 *len) {
// inserire controlli sulla precisione e stereo
// e gestione dei buffer ottimizzata


sound_channel.playing_state = CHANNEL_STATE_PLAYING; sound_channel.output.sample.buffer = (cyg_uint32*)buffer; sound_channel.output.sample.length = *len; sound_channel.output.sample.offset = 0;

sound_channel.output.rotation_number = sound_channel.output.sample.length / sound_channel.output.frag_size;
sound_channel.output.rotation_number += sound_channel.output.sample.length % sound_channel.output.frag_size ? 1 : 0;


sound_channel.output.rotation_count = 0;
sound_channel.output.select_fragment = 0;


int i;
for(i = 0; i < sound_channel.output.rotation_number; i++) {
desc_load_fragment(sound_channel.output.select_fragment,false);
desc_play_fragment(sound_channel.output.select_fragment,false);
sound_channel.output.select_fragment = ++sound_channel.output.select_fragment % sound_channel.output.frag_number;





}




   return ENOERR;
}


//static cyg_uint32* buffer_0;


int main(){

//HAL_DCACHE_SYNC();
//HAL_DCACHE_INVALIDATE_ALL();
//HAL_DCACHE_DISABLE();

sound_init();


cyg_uint32 j; Cyg_ErrNo err;



cyg_uint32 sound_buffer_len=1024*1024;



cyg_uint32* buffer_0 = (cyg_uint32*)malloc(sound_buffer_len);


cyg_uint16 volume = 100; cyg_uint16 volume1 = 10; cyg_uint32 length = sizeof(cyg_uint32); //sound_set_config(CYG_IO_SET_CONFIG_OUT_MASTER_GAIN, &volume, &length); //sound_set_config(CYG_IO_SET_CONFIG_IN_MASTER_GAIN, &volume1, &length);

// err=block_sound_read((void*)buffer_0, &sound_buffer_len);

// err=sound_write( (void*)buffer_0, &sound_buffer_len );


for(;;) { err=start_sound_read((void*)buffer_0, &sound_buffer_len); err=sound_write( (void*)buffer_0, &sound_buffer_len ); } for(;;) {}

}

////////////////////////////////////////////////////////////////////////////
// The required device table structures
////////////////////////////////////////////////////////////////////////////

DEVIO_TABLE(
 unipdpxa_sound_handlers,
 sound_write,
 sound_read,
 sound_select,
 sound_get_config,
 sound_set_config);

DEVTAB_ENTRY(
sound,
CYGDAT_DEVS_SOUND_ARM_XSCALE_UNIPDPXA_DEVTAB_BASENAME,
NULL, // Base device name
&unipdpxa_sound_handlers,
sound_init,
sound_lookup,
NULL); // Private data pointer
-------------------------------------------------------------------------------------------------------------




Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]