public inbox for ecos-devel@sourceware.org
 help / color / mirror / Atom feed
* Error: No rule to make target
@ 2005-02-21 18:01 Andrea Pellegrini
  2005-02-21 18:49 ` Andrew Lunn
  0 siblings, 1 reply; 2+ messages in thread
From: Andrea Pellegrini @ 2005-02-21 18:01 UTC (permalink / raw)
  To: ecos-devel

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
------------------------------------------------------------------------------------------------------------- 


^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: Error: No rule to make target
  2005-02-21 18:01 Error: No rule to make target Andrea Pellegrini
@ 2005-02-21 18:49 ` Andrew Lunn
  0 siblings, 0 replies; 2+ messages in thread
From: Andrew Lunn @ 2005-02-21 18:49 UTC (permalink / raw)
  To: Andrea Pellegrini; +Cc: ecos-devel

On Mon, Feb 21, 2005 at 07:01:08PM +0100, Andrea Pellegrini wrote:
> 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

This all looks OK. One thing to check is if you have the case correct.
ie is you source file realy sound_AC97.c or is it sound_ac97.c?

You can also take a look at the makefile in 
/ecos-c/Cygwin/opt/ecos/sound-unipdpxa_build/devs/sound/arm/xscale/unipdpxa/v2_0'

It might give you some clues.

        Andrew

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2005-02-21 18:49 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-02-21 18:01 Error: No rule to make target Andrea Pellegrini
2005-02-21 18:49 ` Andrew Lunn

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).