CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

struct problem

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
guest
Guest







struct problem
PostPosted: Sat Feb 07, 2004 5:27 pm     Reply with quote

Hello!

I want to write 4 bytes to a struct. I know that the compiler creates "1 byte packets". But I have no idea why the following doesn't give the right result:

the struct:
Code:

struct _s_mp3_header {   //4 bytes       //http://www.id3.org/mp3frame.html
   unsigned   Sync1         :8;

   unsigned   Sync2         :4;   //SyncWord (12 bit)
   unsigned   Id            :1;   //MPEG Version (1bit): 0=MPEG-2 and 1=MPEG-1
   unsigned   Layer         :2;   //MPEG Layer (2bit): 00=not def., 01=LayerIII, 10=LayerII, 11=LayerI
   unsigned   Protection   :1;   //Protection Bit (1bit): Die genaue Funktionsweise ist noch nicht dokumentiert

   unsigned   Bitrate      :4;   //Bitrate (4 bit)
   unsigned SampleFreq   :2;   //Samplingfrequenz (2 bit)
   unsigned   Padding      :1;   //Padding Bit (1 bit): gibt an ob alle anderen Bits genutzt werden, oder ob ungebrauchte Bits aufgefüllt werden sollen
   unsigned Private      :1;

   unsigned   Mode         :2;   //Mode (2 bit): gibt an ob das MP3 File Stereo, Mono oder Joint-Stereo ist
   unsigned   ModeExt      :2;   //Mode Extention (2 bit) nur wenn in Joint-Stereo codiert wird, gibt Frequenzbänder an
   unsigned   Copyright   :1;   //Copyright (1 bit) wenn dieses Bit gesetzt ist ist die Datei urheberrechtlich geschützt
   unsigned   OrigHome      :1;
   unsigned   Emphasis      :2;   //Emphasis (2 bit) zur Rauschunterdrückung, hebt leise Frequenzen an
};




Code:


struct _s_mp3_header h;
word i, tmp;
byte bh, bl;


bh = 0x12;
bl = 0x34;
//swap(bl);
*(&h) = bh;
*(&h+1) = bl;

bh = 0x56;
bl = 0x78;
//swap(bh);
//swap(bl);
*(&h+2) = bh;
*(&h+3) = bl;

printf("\n\rh:%X%X%X%X", *(&h), *(&h+1), *(&h+2), *(&h+3));

printf("\n\rSync:0x%4lX", ((word)h.Sync1<<4) | h.Sync2);
printf("\n\rId:%X", h.Id);
printf("\n\rLayer:%X", h.Layer);
printf("\n\rProtection:%X", h.Protection);

printf("\n\rBitrate:%X", h.Bitrate);
printf("\n\rSampleFreq:%X", h.SampleFreq);
printf("\n\rPadding:%X", h.Padding);
printf("\n\rPrivate:%X", h.Private);
   
printf("\n\rMode:%X", h.Mode);
printf("\n\rModeExt:%X", h.ModeExt);
printf("\n\rCopyright:%X", h.Copyright);
printf("\n\rOrigHome:%X", h.OrigHome);
printf("\n\rEmphasis:%X", h.Emphasis);


The output is:

h:12345678
Sync:0x0124
Id:01
Layer:01
Protection:00
Bitrate:06
SampleFreq:01
Padding:01
Private:00
Mode:00
ModeExt:02
Copyright:01
OrigHome:01
Emphasis:01

it should be in the same order as in the structure:
Sync:0x0123
...etc


Thanx for some hints :-)
Matthias
guest
Guest







PostPosted: Sat Feb 07, 2004 5:29 pm     Reply with quote

sorry i forgot:

using PCH 3.181
and PICLF452
Guest
Guest







An empirical approach
PostPosted: Sat Feb 07, 2004 7:28 pm     Reply with quote

I don't know the answer, but you might try this approach to figuring out where the compiler is putting the elements of the structure. That might lead you to the way it organizes it.

Code:
struct _s_mp3_header h;

void clear_struct(void)
{
   byte b;

   b = 0;
   *(&h) = b;
   *(&h+1) = b;
   *(&h+2) = b;
   *(&h+3) = b;
}

main()
{
   clear_struct();
   printf("\r\nh:%X%X%X%X", *(&h), *(&h+1), *(&h+2), *(&h+3));

   // for each element of the structure, put in a value and check where it goes
   h.Sync1 = 0x0123;
   printf("\r\nh:%X%X%X%X", *(&h), *(&h+1), *(&h+2), *(&h+3));
   clear_struct();
}
Guest
Guest







Compiler builds from the LSB
PostPosted: Sun Feb 08, 2004 10:45 am     Reply with quote

I played with this a bit. It looks like the CCS compiler builds bit fields into structures starting from the least significant bit. (Now that I've typed all this, somebody will point out where in the documentation it says this.) So, where you might expect
Code:
struct s {
   unsigned s :4;
   unsigned i :1;
   unsigned l :2;
   unsigned p :1;
}

to give you a byte like (ssssillp) it actually gives you (pllissss). The bits stay in order. So
Code:
s=0b1011;

gives you (00001011).

Here's the result I got, and the code I used.
Code:
#include <18f452.h>
#device ICD=TRUE
#device adc=10
#use delay(clock=20000000)
#fuses NOWDT, HS, PUT, NOLVP
#use rs232(baud=57600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)


struct _s_mp3_header {
   unsigned Sync1       :8;

   unsigned Sync2       :4;
   unsigned Id          :1;
   unsigned Layer       :2;
   unsigned Protection  :1;

   unsigned Bitrate     :4;
   unsigned SampleFreq  :2;
   unsigned Padding     :1;
   unsigned Private     :1;

   unsigned Mode        :2;
   unsigned ModeExt     :2;
   unsigned Copyright   :1;
   unsigned OrigHome    :1;
   unsigned Emphasis    :2;
};


struct _s_mp3_header h;

void clear_struct(void)
{
   byte b;

   b = 0;
   *(&h) = b;
   *(&h+1) = b;
   *(&h+2) = b;
   *(&h+3) = b;
}

main()
{
   clear_struct();
   printf("\r\nClear       h:%X%X%X%X", *(&h), *(&h+1), *(&h+2), *(&h+3));

   h.Sync1 = 0x23;
   h.Sync2 = 0x01;
   printf("\r\nSync        h:%X%X%X%X", *(&h), *(&h+1), *(&h+2), *(&h+3));
   clear_struct();

   h.Id = 1;
   printf("\r\nId          h:%X%X%X%X", *(&h), *(&h+1), *(&h+2), *(&h+3));
   clear_struct();

   h.Layer = 3;
   printf("\r\nLayer       h:%X%X%X%X", *(&h), *(&h+1), *(&h+2), *(&h+3));
   clear_struct();

   h.Protection = 1;
   printf("\r\nProtection  h:%X%X%X%X", *(&h), *(&h+1), *(&h+2), *(&h+3));
   clear_struct();

   h.Bitrate = 15;
   printf("\r\nBitrate     h:%X%X%X%X", *(&h), *(&h+1), *(&h+2), *(&h+3));
   clear_struct();

   h.SampleFreq = 3;
   printf("\r\nSampleFreq  h:%X%X%X%X", *(&h), *(&h+1), *(&h+2), *(&h+3));
   clear_struct();

   h.Padding = 1;
   printf("\r\nPadding     h:%X%X%X%X", *(&h), *(&h+1), *(&h+2), *(&h+3));
   clear_struct();

   h.Private = 1;
   printf("\r\nPrivate     h:%X%X%X%X", *(&h), *(&h+1), *(&h+2), *(&h+3));
   clear_struct();

   h.Mode = 3;
   printf("\r\nMode        h:%X%X%X%X", *(&h), *(&h+1), *(&h+2), *(&h+3));
   clear_struct();

   h.ModeExt = 3;
   printf("\r\nModeExt     h:%X%X%X%X", *(&h), *(&h+1), *(&h+2), *(&h+3));
   clear_struct();

   h.Copyright = 3;
   printf("\r\nCopyright   h:%X%X%X%X", *(&h), *(&h+1), *(&h+2), *(&h+3));
   clear_struct();

   h.OrigHome = 1;
   printf("\r\nOrigHome    h:%X%X%X%X", *(&h), *(&h+1), *(&h+2), *(&h+3));
   clear_struct();

   h.Emphasis = 3;
   printf("\r\nEmphasis    h:%X%X%X%X", *(&h), *(&h+1), *(&h+2), *(&h+3));

   while (TRUE)
   {
   }
}

Code:
Clear       h:00000000
Sync        h:23010000
Id          h:00100000
Layer       h:00600000
Protection  h:00800000
Bitrate     h:00000F00
SampleFreq  h:00003000
Padding     h:00004000
Private     h:00008000
Mode        h:00000003
ModeExt     h:0000000C
Copyright   h:00000010
OrigHome    h:00000020
Emphasis    h:000000C0
Guest
Guest







Oops. I forgot something.
PostPosted: Sun Feb 08, 2004 10:51 am     Reply with quote

Since I think your structure is arranged from MSB to LSB instead of the CCS way, I think you may need to rearrange your structure like this:
Code:
struct _s_mp3_header {
   unsigned Emphasis    :2;
   unsigned OrigHome    :1;
   unsigned Copyright   :1;
   unsigned ModeExt     :2;
   unsigned Mode        :2;

   unsigned Private     :1;
   unsigned Padding     :1;
   unsigned SampleFreq  :2;
   unsigned Bitrate     :4;

   unsigned Protection  :1;
   unsigned Layer       :2;
   unsigned Id          :1;
   unsigned Sync2       :4;

   unsigned Sync1       :8;
};
guest
Guest







no thats not right
PostPosted: Sun Feb 08, 2004 11:16 am     Reply with quote

Hello!

Thanks for your help. I knew that there can be such a problem, but i was a little bit confuesed...
Can i configure this anywhere?

it should be arranged like this:

Code:

struct _s_mp3_header {
   unsigned   Sync1:8;

   unsigned   Protection   :1;
   unsigned   Layer      :2;
   unsigned   Id      :1;
   unsigned   Sync2      :4;

   unsigned Private      :1;
   unsigned   Padding      :1;
   unsigned SampleFreq   :2;
   unsigned   Bitrate      :4;

   unsigned   Emphasis      :2;
   unsigned   OrigHome      :1;
   unsigned   Copyright   :1;
   unsigned   ModeExt      :2;
   unsigned   Mode         :2;
};


It seems that only the bit alignment is changes, not the byte-blocks in the structure.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group