Newsgroup: it.hobby.elettronica.digitale
Titolo: Semplice wav player (uC)

Volevo convertire in uC il semplice wav player che, a detta
dell'autore, funziona con swordfish.
http://www.sfcompiler.co.uk/wiki/pmwiki.php?n=SwordfishUser.SDMMCWavPlayer
to usando un P18F4620@32MHz.
Il problema è che il led spia del buffer vuoto rimane sempre accesso,
come se non si riuscisse a leggere dalla MMC in tempo. Proverò ad
aumentare il buffer o a cambiare quarzo ma viene il dubbio che  uC
acceda alla MMC card in modo differente dal compilatore Swordfish
Dato che nn sono una mago col C, allego il file.
Un grazie anticipato a chi vorrà darmi una mano.
Ps: Il file wav è mono 8 bit a 16kHz. E' un file di circa 200Kb.
unsigned short init_ok;
unsigned short car_blink;
char filename[14] = "TEST8M16WAV" ;         // File names
unsigned long  i, size;
unsigned short caracter;
unsigned int   BufferSize = 500  ;                // buffer to avoid
glitches
unsigned int     TimerReload = 65036 ;              // alter for
different sample rates
unsigned short     TimerReloadH = 0xFE ;
unsigned short     TimerReloadL = 0x0C ;
unsigned int     WritePointer, ReadPointer ;   // read/write pointers
in
unsigned int     Buffer[500];
unsigned long    DataSize;                // size of WAV data in file
unsigned long    FileLen ;
/* void ScriviLong (unsigned long valore) {
  char ltxt[12];
  LongToStr(valore, ltxt);
  lcd_out(1,3,ltxt);
  delay_ms(900);
}  */
void GoDac (unsigned short valore) {
       PORTE.F1 = 1;
      PORTE.F0 = 1;
     Soft_I2C_Start();
  Soft_I2C_Write(0x58);
  Soft_I2C_Write(0);
  Soft_I2C_Write(valore);
  Soft_I2C_Stop();
      // PORTE.F1 =0;
      //PORTE.F0 = 0;
//char dactxt[4];
     //bytetostr(valore,dactxt);
     //lcd_out(10,1,dactxt) ;
}
void interrupt() {
  pie1.TMR1IE=0;
  if (PIR1.TMR1IF=1)  {
          TMR1L = TimerReloadL ;
          TMR1H = TimerReloadH ;
          if (ReadPointer==WritePointer) {
             PORTE.F0=1;
             }
          else
              {
              ReadPointer=ReadPointer+1;
              if (ReadPointer==BufferSize) {
                 ReadPointer=0;
                 }
              PORTD=buffer[ReadPointer];
              //godac(buffer[ReadPointer]);
              }
          PIR1.TMR1IF=0;
     }
    pie1.TMR1IE=1;
       //    PORTE.F0=0;
}
int ReadFmt() {
char txt[4];
unsigned short    index ;
unsigned short dummyByte;
unsigned int dummyWord;
unsigned long dummylong;
     //RIFF header
    for (index=1;index<=12;index++)
        {
        MMC_Fat_Read(&dummyByte);
        };
  MMC_Fat_Read(&dummyByte);
  if (dummybyte !=102)          //f
     {
      return 0 ;
     }
  MMC_Fat_Read(&dummyByte);
  if (dummybyte !=109)             //m
     {
      return 0 ;
     }
  MMC_Fat_Read(&dummyByte);      //t
  if (dummybyte !=116)
     {
      return 0 ;
     }
 MMC_Fat_Read(&dummyByte);       //" "
  if (dummybyte !=32)
     {
      return 0 ;
     }
   for (index=1;index<=4;index++)   //fmt size
        {
        MMC_Fat_Read(&dummyByte);
        };
   MMC_Fat_Read(&dummyByte);
   dummyword=dummybyte;
   MMC_Fat_Read(&dummyByte);
   dummyword=dummyword+(dummybyte << 8);
    if (dummyword !=1)         //check PCM uncompressed
     {
      return 0 ;
     }
   MMC_Fat_Read(&dummyByte);
   dummyword=dummybyte;
   MMC_Fat_Read(&dummyByte);
   dummyword=dummyword+(dummybyte << 8);
    if (dummyword !=1)         //check 1 ch mono
     {
      return 0 ;
     }
   MMC_Fat_Read(&dummyByte);
   dummyword=dummybyte;
   MMC_Fat_Read(&dummyByte);
   dummyword=dummyword+(dummybyte << 8);
    if (dummyword !=16000)         //check 16k
     {
      return 0 ;
     }
    MMC_Fat_Read(&dummyByte);
    MMC_Fat_Read(&dummyByte);
   for (index=1;index<=18;index++)   //vado al data
        {
        MMC_Fat_Read(&dummyByte);
        };
   MMC_Fat_Read(&dummyByte);
   datasize=dummybyte;
   MMC_Fat_Read(&dummyByte);
   dummylong=dummybyte;
   dummylong=dummylong << 8;
   datasize=datasize+ dummylong   ;
   MMC_Fat_Read(&dummyByte);
   dummylong=dummybyte;
   dummylong=dummylong << 16;
   datasize=datasize+ dummylong  ;
   MMC_Fat_Read(&dummyByte);
   dummylong=dummybyte;
   dummylong=dummylong << 24 ;
   datasize=datasize+ dummylong ;
   for (index=1;index<=4;index++)   //vado al data
        {
        MMC_Fat_Read(&dummyByte);
        };
  return 1;
}
void SuonaFile (char *pFile)
{
unsigned int    TempWritePointer ;
unsigned short localByte;
char txt[4];
char wtxt[6];
 char ltxt[12];
init_ok=Mmc_Fat_Assign(pFile,0);
Mmc_Fat_Reset(&FileLen);
TMR1L = TimerReloadL ;
TMR1H = TimerReloadH ;
ReadPointer = 0  ;                    // initialise pointers
WritePointer = 0;
if (init_ok==1) {
   Lcd_out(2, 1, pFile);
   }
     else
     {
       Lcd_Out(2, 1, "NO FILE    ");
     }
if (ReadFmt()=1)
  {
     Lcd_Out(1, 1, "FMT     OK ");
     DELAY_MS(900);
     Lcd_Out(1, 1, "             ");
     Lcd_Out(1, 1, "datasize");
     DELAY_MS(900);
     longtostr(DataSize,ltxt);
     Lcd_Out(1, 1, ltxt);
     DELAY_MS(900);
     Lcd_Out(1, 1, "Filesize");
     DELAY_MS(900);
     longtostr(FileLen,ltxt);
     Lcd_Out(1, 1, ltxt);
     DELAY_MS(900);
    do
     {                           // fill buffer initially
        WritePointer=WritePointer+1;
        MMC_Fat_Read(&localByte);
         Buffer[WritePointer] =localbyte;
        DataSize=DataSize-1;
      }  while ((WritePointer != BufferSize - 1) &&
(WritePointer<FileLen)); //| SD.EOF
     Lcd_Out(1, 1, "FMT buf OK ");
     DELAY_MS(900);
      wordToStr(WritePointer,wtxt);
      Lcd_Out(1, 1, wtxt);
     DELAY_MS(900);
     Lcd_Out(1, 1, "               ");
      PIE1.TMR1IE = 1;
     do
     {
       TempWritePointer = WritePointer;
       TempWritePointer=TempWritePointer+1;
       if (TempWritePointer == BufferSize) {
            TempWritePointer = 0;
              }
        while (TempWritePointer == ReadPointer)  {
            PORTE.F1 = 1;
            } ;
       PORTE.F1 = 0;
       WritePointer = TempWritePointer;
       MMC_Fat_Read(&localByte);
       Buffer[WritePointer] =localbyte;
       DataSize=DataSize-1;
      }  while ((DataSize!=0)  && (WritePointer<FileLen)) ; // Or
Sd.Eof
  }
  else
    {
      Lcd_Out(1, 1, "FMT ERRATO");
     }
  do
    {
      }
  while  (ReadPointer == WritePointer);
  PIE1.TMR1IE = 0 ;
  PORTE=0;
  Lcd_Out(1, 1, "fine      ");
}
void main() {
TRISA=0;
TRISB = 0;
TRISC = 0;
TRISD = 0;
TRISE = 0;
PORTE = 0;
//T0CON  = 0xC4;           // assign prescaler to TMR0
INTCON = 0xC0;
ADCON0  = 0;
ADCON1  = 0x0F;          // disable ADC
T1CON=0;
T1CON.TMR1ON=1;
PIE1=0;
PIR1 = 0  ;
PIR1.TMR1IF = 1;
INTCON.GIE = 1;
RCON.IPEN = 0;
                // PORTB is output
  Lcd_Init(&PORTB);         // Initialize LCD connected to PORTB
  Lcd_Cmd(Lcd_CLEAR);       // Clear display
  Lcd_Cmd(Lcd_CURSOR_OFF);  // Turn cursor off
  Lcd_Out(1, 1, "test");      // Print text to LCD, 2nd row, 1st
column
  Lcd_Out(2, 1, "MMC...");      // Print text to LCD, 2nd row, 1st
column
  // Initialize MMC communication
 Spi_Init_Advanced(MASTER_OSC_DIV64, DATA_SAMPLE_MIDDLE, CLK_IDLE_LOW,
LOW_2_HIGH);
  car_blink=32;
  do
   {
      init_ok=Mmc_Fat_Init(&PORTC,2);
      Lcd_Out(2, 1, "INIT Error");
      delay_ms(1000);
      if (car_blink==32)  {
        car_blink=42 ;
       }
       else {
        car_blink=32;
       }
       Lcd_chr(2, 14, car_blink);
    }
  while (init_ok != 0);
  Spi_Init_Advanced(MASTER_OSC_DIV16, DATA_SAMPLE_MIDDLE,
CLK_IDLE_LOW, LOW_2_HIGH);
  Lcd_Out(2, 1, "INIT OK        ");      // Print text to LCD, 2nd
row, 1st column
                      //sda,cl
Soft_I2C_Config(&PORTA,0,1);
i=0;
 // suonafile("TEST8M16WAV");
 //PROVA123TXT
 suonafile(filename);
}//~!

 ha scritto nel messaggio 
news:1193120449.7...@q3g2000prf.googlegroups.com...


 prima di stendere tutto il firmware!!)
Niente I2C... uso  R/2R come nello schema...
Cmq x la cronaca ho provati anche velocità da 40Mhz, 48Mhz (con quarzo
a 12MHz),
ho provato a diminuire il sample rate da 8Khz, ma il buffer me lo dà
sempre pieno....
Boh...

 Boh...
Hai provato prima i singoli blocchi?
Intendo dire: inizializzazione/lettura vanno a buon fine?


 ICQ UIN# : 104528066

 l'header del file wav senza problemi.
A colpo d'occhio ho notato un'altra cosa. Scusami ma non ho tempo di starci 
tanto dietro:
Spi_Init_Advanced(MASTER_OSC_DIV16, DATA_SAMPLE_MIDDLE,
CLK_IDLE_LOW, LOW_2_HIGH);
A parte che l'inizializzazione la fai con fspi = fclk/64 e poi continui ad 
usarla a fclk/16  ,  voglio ricordarti che per la secure digital ti conviene 
usare   spi_init();   per utilizzare il modulo alla massima velocità 
consentita (fclk/4, CPOL=0 , CPHA=0)
Ciao
CG 


Putroppo io non ne capisco troppo di SD nè di SPI, ma il manuale
mikroC e gli esempi riportano proprio la modalità che ho usato, xkè
fuorviano l'utente finale in questo modo ?
Tu come faresti quindi ?
Tratto dall'help in linea...
Mmc_Init
Prototype unsigned char Mmc_Init(unsigned short *port, unsigned short
pin);
Returns
0 - if MMC/SD card was detected and successfully initialized
1 - otherwise
Description Initializes MMC through hardware SPI interface.
Parameters:
port: chip select signal port address.
cspin: chip select pin.
Requires The appropriate hardware SPI module must be previously
initialized.
Example #include <spi_const.h>
...
// Initialize the SPI module
Spi_Init_Advanced(_SPI_MASTER, _SPI_8_BIT, _SPI_PRESCALE_SEC_1,
_SPI_PRESCALE_PRI_64,_SPI_SS_DISABLE,
                  _SPI_DATA_SAMPLE_MIDDLE, _SPI_CLK_IDLE_HIGH,
_SPI_ACTIVE_2_IDLE);
// Loop until MMC is initialized
while (Mmc_Init(&PORTG, 9))
  ;
// Reinitialize the SPI module at higher speed (change primary
prescaler).
Spi_Init_Advanced(_SPI_MASTER, _SPI_8_BIT, _SPI_PRESCALE_SEC_1,
_SPI_PRESCALE_PRI_4,_SPI_SS_DISABLE,
                  _SPI_DATA_SAMPLE_MIDDLE, _SPI_CLK_IDLE_HIGH,
_SPI_ACTIVE_2_IDLE);

 Tu come faresti quindi ?
L'help fa piuttosto schifo, quelli sono problemi che gli sono stati 
segnalati più volte....se provi la funzione dell'esempio NON FUNZIONA
la SD necessita del bus SPI inizializzato con CPOL=0 e CPHA=0, quindi devi 
mettere
spi_init();
visto che non hai altri dispositivi su SPI e non devi commutare la modalità, 
non ti rimane che utilizzare i comandi per la secure digital.
se vuoi sapere cos'è l'SPI :
http://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus
ti sconsiglio, però, di affrontare progetti di cui non hai la più pallida 
idea di cosa stai facendo, sia a livello analogico sia digitale, perchè 
rischi di buttare soldi e tempo
Ciao
CG 

 rischi di buttare soldi e tempo
io lo faccio per hobby non per lavoro... infatti il ng titola
it.hobby.*:

 it.hobby.*:
E' vero, ma a maggior ragione, visto che ti dedichi all'elettronica per 
hobby, se fai un progetto cerca di evitare di stendere circuiti di cui non 
conosci il funzionamento giusto per vederli funzionare, perchè rischi di 
perderci un sacco di tempo a causa magari di sviste o datasheet letti 
velocemente nella foga di accendere il circuito :)
Spero non te la sia presa, il mio era solo un consiglio, visto che ci ho 
sbattuto la testa tempo fa e più volte :)
Ciao
-- 
____________________
      CG Engineering
 Lab. Ricerca & Sviluppo
********************
Skype : cg_ingegnering
MSN : 
cgaudiola...@interfree.it
ICQ UIN# : 104528066

 sbattuto la testa tempo fa e più volte :)
Beh dai allora posso "mungerti" di consigli utili  ;)
ciao

... ma questa č un'altra materia. !
E' come puoi considerare le librerie che ti forniscono i compilatori, perň 
devi conoscere cosa sta sotto perchč spesso e volentieri hai altri problemi, 
per esempio risorse condivise, e quando vai a scrivere il firmware non hai 
semafori, monitor e compagnia bella. Inoltre devi averlo previsto in 
hardware.
La pappa scodellata spesso funziona bene, ma quando si sviluppano sistemi 
embedded molto piů volentieri preferirei usare librerie open-source (come 
quelle del compilatore CCS, per esempio), che ti permettono di risparmiare 
RAM e ROM e di ottimizzarle per la funzione che deve svolgere il tuo 
sistema. Se stai iniziando, comunque, non č male che tu lo faccia su un 
compilatore piuttosto assembler-like come quello di mikroelektronika, che a 
prescindere dai difetti che ha, ti COSTRINGE a leggerti il datasheet del 
microprocessore che usi
Ciao
CG