cannot explain

General discussion on mikroC.
Post Reply
Author
Message
sisko
Posts: 63
Joined: 02 Jun 2005 09:48
Contact:

cannot explain

#1 Post by sisko » 22 Jul 2005 16:59

Hi,

from CF-Card I read 4 bytes which determine the length of a file. These 4 bytes are added together to a long-variable for further calculating the sectors on the CF-card.

Code: Select all

          filesize = filesize + Cf_Read_Byte();
          filesize = filesize + (Cf_Read_Byte() << 8);
          filesize = filesize + (Cf_Read_Byte() << 16);
          filesize = filesize + (Cf_Read_Byte() << 24);

          usart_sendlong(filesize);
The result is :
Received: 0x20 0x20 0x20 0x20 0x20 0x20 0x32 0x36 0x34 0x39 0x39

When I replace the CF_Read_Byte() with the values from the CF-Card, I get the correct value for the filesize :

Code: Select all

          filesize = filesize + 0x35;
          filesize = filesize + (0x06 << 8);
          filesize = filesize + (0x40 << 16);
          filesize = filesize + (0x00 << 24);

          usart_sendlong(filesize);
The result is :
Received: 0x20 0x20 0x20 0x20 0x34 0x31 0x39 0x35 0x38 0x39 0x33

This is the code of the usart_sendlong:

Code: Select all

void Usart_SendLong(long NumToSend)
{
 char * text;

  LongToStr(NumToSend,text);
  while(*text){
    USART_Write(*text++);
  }
}
Any ideas ? At the moment I want to throw everything in a corner and go home. :cry:
Regards, Gunther

anton
Posts: 807
Joined: 23 Sep 2004 09:16
Location: South-Africa
Contact:

#2 Post by anton » 22 Jul 2005 22:19

Musn't the first line only be filesize + Cf_Read_Byte?

Code: Select all

filesize = Cf_Read_Byte();
          filesize = filesize + (Cf_Read_Byte() << 8);
          filesize = filesize + (Cf_Read_Byte() << 16);
          filesize = filesize + (Cf_Read_Byte() << 24);

          usart_sendlong(filesize);
Another proud user of LV 24-33A Development System and mikroPascal PRO for dsPIC :)
PortA not working? Add CMCON := 7; PortD not working? Add ADCON1 := 6;
To paste code on the forum, please use the [b] Code [/b] button !! ;)

sisko
Posts: 63
Joined: 02 Jun 2005 09:48
Contact:

#3 Post by sisko » 24 Jul 2005 09:14

filesize is set to 0 at the beginning of the function.

Code: Select all

filesize=0;
The curious thing is that at the lines befor reading the filesize, I calculate the beginning of the file in the exact same manner. There it works.
Tomorrow I will post the complete code.
Regards, Gunther

anton
Posts: 807
Joined: 23 Sep 2004 09:16
Location: South-Africa
Contact:

#4 Post by anton » 24 Jul 2005 09:55

Cant you do something like this?

Code: Select all

          var dummy : byte;

          filesize = Cf_Read_Byte();
          dummy := CF_Read_Byte << 8;
          filesize = filesize + dummy;
          dummy := CF_Read_Byte << 16;
          filesize = filesize dummy;
          dummy := CF_Read_Byte <<24;
          filesize = filesize + dummy;

          usart_sendlong(filesize);
Another proud user of LV 24-33A Development System and mikroPascal PRO for dsPIC :)
PortA not working? Add CMCON := 7; PortD not working? Add ADCON1 := 6;
To paste code on the forum, please use the [b] Code [/b] button !! ;)

sisko
Posts: 63
Joined: 02 Jun 2005 09:48
Contact:

#5 Post by sisko » 25 Jul 2005 07:16

Here is the complete function :

Code: Select all

void CF_Play_MP3(int dirEntry)
{
  long cluster_begin_lba;
  long filestart;
  long filesize;
  long lba_begin;
  int i,k;
  char CFData;

  // find the beginning of the directory
        cluster_begin_lba = CF_get_CBL();
        Cf_Read_Init(cluster_begin_lba,1);

  // now read the wanted dirEntry
        filestart=0;
        // skip data on CF-card before the searched entry
        for (i=0; i<((dirEntry-1)*32); i++)
        {
          CFData=Cf_Read_Byte();
        }
        // skip the first 20 bytes
        for (i=0; i<20; i++)
        {
          CFData=Cf_Read_Byte();
        }
          filestart += Cf_Read_Byte()<<16;
          filestart += Cf_Read_Byte()<<24;
        // skip 4 bytes
        for (i=0; i<4; i++)
        {
          CFData=Cf_Read_Byte();
        }
          filestart += Cf_Read_Byte();
          filestart += Cf_Read_Byte()<<8;

// until here, everything will be calculated perfectly !!

// here begins the 'black hole'

          filesize = 0;
          filesize = filesize + Cf_Read_Byte();
          filesize = filesize + (Cf_Read_Byte() << 8);
          filesize = filesize + (Cf_Read_Byte() << 16);
          filesize = filesize + (Cf_Read_Byte() << 24);

/*
          // this calculates the correct value for filesize
          filesize = filesize + 0x35;
          filesize = filesize + (0x06 << 8);
          filesize = filesize + (0x40 << 16);
          filesize = filesize + (0x00 << 24);

          usart_sendlong(filesize);
*/

// This is the correct calculated value of filesize:
//filesize=0x00400635;   // 4195893 Bytes



// From here, everything is working perfectly again

  lba_begin = cluster_begin_lba+(filestart-1);

  // Read MP3-Data and play
  GIO1=1;
  for (k=0; k<(filesize/512); k=k+1)
  {
    Cf_Read_Init((lba_begin+k),1);

    for (i=0; i<=511; i++)
    {
      VS1001_MP3(Cf_Read_Byte());
      do
        asm nop;
      while(DREQ==0);
    }
  }
  Cf_Read_Init((lba_begin+k+1),1);

    for (i=0; i<=(filesize-(k*512)); i++)
    {
      VS1001_MP3(Cf_Read_Byte());
      do
        asm nop;
      while(DREQ==0);
    }
}
I have no idea. I tried anton's version and many other ... the result is a wrong value for filesize. Is it the typeconversion between char (cf_read_byte) and long(filesize) ?

Can someone from the microC-team look upon this problem ... please.
Regards, Gunther

pizon
mikroElektronika team
Posts: 823
Joined: 11 Oct 2004 08:53

#6 Post by pizon » 25 Jul 2005 09:19

The correct snippet is:

Code: Select all

          filesize = 0;
          filesize = filesize + Cf_Read_Byte();
          filesize = filesize + (Cf_Read_Byte() << 8);
          filesize = filesize + ((long)Cf_Read_Byte() << 16);
          filesize = filesize + ((long)Cf_Read_Byte() << 24);
It is about the typecasting (implicit type conversion), but for the << operation. Cf_Read_Byte() returns result of type unsigned short, so the << operation is performed on the level of unsigned int, which is standard C implicit type conversion. When you do the first shift ( ...<< 8 ), the result stays within the two-byte size, but for the next two it goes out of the int scope, so you have to perform implicit typecast to make it work. Please refer to mikroC Help, the 'Standard Conversions' topic.

For this particular purpose (operating between the variables of different sizes) you can also use the built-in mikroC functions that are meant for this purpose: Lo(), Hi(), Higher() and Highest(). Using them, the abovementioned snippet can be written as:

Code: Select all

          filesize = Cf_Read_Byte();
          Hi(filesize) = Cf_Read_Byte();
          Higher(filesize) = Cf_Read_Byte();
          Highest(filesize) = Cf_Read_Byte();
Take a look in mikroC FAQ about more detail on this.
pizon

sisko
Posts: 63
Joined: 02 Jun 2005 09:48
Contact:

#7 Post by sisko » 25 Jul 2005 09:58

Phew !!! Thank you very much. The second code-snippet works fine. :D :D :D

Sorry for overlooking the FAQ. I was concentrated to the PDF-Manual of MicroC and there are these functions Hi(), Higher(), ... not described.
Regards, Gunther

pizon
mikroElektronika team
Posts: 823
Joined: 11 Oct 2004 08:53

#8 Post by pizon » 25 Jul 2005 14:01

sisko wrote:I was concentrated to the PDF-Manual of MicroC and there are these functions Hi(), Higher(), ... not described.
At first we introduced these functions for internal use only, since they're not part of the ANSI C Standard, but they eventually proved to be very useful, so we decided to make them 'public' 8) .
pizon

sisko
Posts: 63
Joined: 02 Jun 2005 09:48
Contact:

#9 Post by sisko » 25 Jul 2005 14:27

These functions made me smiling and more relaxed for today. My project is a big step further.

Thanks again.
Regards, Gunther

Post Reply

Return to “mikroC General”