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

Shifting data out of a pin to load a pll register correctly

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







Shifting data out of a pin to load a pll register correctly
PostPosted: Fri Jul 07, 2006 7:27 pm     Reply with quote

Hi all, I am having a difficult time trying to get my head around the
best method of shifting data out of a pin so as to load the registers
correctly in a pll, so perhaps some of you can help me out.

The device i am using is a ADF4110 by analog devices the register bit width that I am trying to load has a total of 24 bits. But that register is made up like so.

[ >>>>>>>>>>>>>>>> N Register <<<<<<<<<<<<<<<<<<<<<<]

CP [ 13 BIT B COUNTER ] 6 BIT A COUNTER Control bits
[] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] []

I have 4 variables each 8 bits long. The width of each of the variables
does not exceed the bit width of each counter.

CP, BCOUNT, ACOUNT, CB

So in-order to load the register correctly I need to shift out the msb of
each variable into their respective counters in the correct order. What would be a good method to do this. ? I was thinking of breaking each
part down into individual for loops, load 3bits, 13bits etc but was not sure.

I am using pins RC3 for clock and RC4 For the data out pin.

A small example would be very helpful to get me going in the right direction.

Thanks for your help Steve.
epideath



Joined: 07 Jun 2006
Posts: 47

View user's profile Send private message

PostPosted: Fri Jul 07, 2006 9:35 pm     Reply with quote

I would probably do something like this:

Code:

int8 i;
int32 command = 0;
int8 CP = 1;
int16 BCOUNT=0x1234;
int8 ACOUNT= 0x12;
int8 CB=0x07;


command = (CP<<23);
command |= (((int32)BCOUNT & 0x1FFF)<<10);
command |= (((int16)ACOUNT & 0x3F)<<4);
command |= (CB & 0x0F);

for(i=0; i<24; i++) {
   output_bit(PIN_B4, command & 1);
   command >>=1;
   output_low(PIN_B3);
   output_high(PIN_B3);
}

//if you need to go MSB first then just reverse it.
//for(i=0;i<24;i++) {
//    output_bit(PIN_B4, bit_test(command, 23)); //bit 23
//    command <<= 1;
//    clock it out.
//}


Hope this helps.
Guest








PostPosted: Sat Jul 08, 2006 1:56 pm     Reply with quote

Hi epideath.

Thanks for taking the time to write back.

From the code It looks like you mask each value of the variable
with the actual bit width of each variable first.

like the bcount is only 12 bits wide, so that gets anded with FFF and
then you shift those 12 bits left until the MSB of bcount is at bit position
21 of the 32bit int command. This looks ok.

in the code you have

command |= (((int32)BCOUNT & 0x1FFF)<<10);

What does the | do in the code line above.

and in the for loop

output_bit(PIN_B4, command & 1);

what does the command & 1 do

Thanks again Steve.
epideath



Joined: 07 Jun 2006
Posts: 47

View user's profile Send private message

PostPosted: Sat Jul 08, 2006 3:41 pm     Reply with quote

The |= will OR the bits with the bits already set in command.

The & is AND so in this case we are masking all bits except the first. (command AND 0x01) It will be either a 0 or 1.

Hope this helps.
Guest








PostPosted: Sun Jul 09, 2006 12:15 am     Reply with quote

Well getting closer,

I am curious as to why the values need to be ored and anded.
is there a particular reason why ?, I cant seem to see it.

command = (CP<<23);
command |= (((int32)BCOUNT & 0x1FFF)<<10);
command |= (((int16)ACOUNT & 0x3F)<<4);
command |= (CB & 0x0F);

Can I not just shift the values in the bcount,acount into the correct
LSB bit position of "command" like so and then output the command
variable.

command = (CP<<23);
command = (BCOUNT<<10);
command = (ACOUNT<<4);
command = (CB & 0x0F);

My thinking was that as long as the value of bcount,acount did not
exceed the bit width of the actual register I would be ok. Am I way off
base, what you think.

Thanks again Steve
epideath



Joined: 07 Jun 2006
Posts: 47

View user's profile Send private message

PostPosted: Sun Jul 09, 2006 10:26 am     Reply with quote

If you don't OR the bits as you suggested then the value of command will be replaced each time with the new shifted value. So in your example the value of command would equal the shifted value of CB the last statement.

To do what you need to do can probably be done in several ways. I jsut gave you one idea. Basically what you are trying to do is this:

Say

CP = 1; 0b00000001
BCOUNT = 0b0001111111111111
ACOUNT = 0b00111111
CB = 0b00001111

The reason for the AND is to mask off any extra bits. This can probably be removed. As long as you know the values of these will never exceed the bit field widths you stated earlier.

what we are attempting to do is this. we start with a 32 bit value, we only need 24 bits total though

Code:

    int32 command = 0b00000000 00000000 00000000 00000000

so after we shift CP 23 bits we will have the following
     command = 0b00000000 10000000 00000000 000000000

Then we shift the BCOUNT value and OR it with what was in CP already

     command = 0b00000000 10000000 00000000 00000000
|=             0b00000000 01111111 11111100 00000000
     command = 0b00000000 11111111 11111100 00000000

Then we OR the ACOUNT value with command as follows:
     command = 0b00000000 11111111 11111100 00000000
|=                               0b00000011 11110000
     command = 0b00000000 11111111 11111111 11110000

Then finally we OR the last value CP
     command = 0b00000000 11111111 11111111 11110000
|=                                        0b00001111                   
     command = 0b00000000 11111111 11111111 11111111


So you can see that if we don't mask off the extra bits and they happen to be on when we OR the values they could over write bits already set. If they are forced to zero then they will never over write bits previously set.

There are other ways of doing what you need. Another way that this can be done is to send the data out each time you test a new bit. I personally don't think this is as efficient or easier to understand. But it could go something like below.

Code:

    output_bit(PIN_B4, bit_test(CP,0));   //set output to 0 or 1 based on bit test
    output_low(PIN_B3);
    output_high(PIN_B3);
    for(i=0; i<14;i++) {
         output_bit(PIN_B4, bit_test(BCOUNT,i));  send each bit out
         output_low(PIN_B3);
         output_high(PIN_B3);
    }
    for(i=0; i<6;i++) {
         output_bit(PIN_B4, bit_test(ACOUNT,i));  send each bit out
         output_low(PIN_B3);
         output_high(PIN_B3);
    }
    for(i=0; i<4;i++) {
         output_bit(PIN_B4, bit_test(CP,i));  send each bit out
         output_low(PIN_B3);
         output_high(PIN_B3);
    }


Well as you can see this will require a bit more time to execute and it will most likely take up more memory.

There are other ways to do what you want, there may even be a better way to do than what I originally posted. If there is then maybe someone else can post it. The way that I typically do this sort of thing is as I originally posted.

Regards
Guest








PostPosted: Sun Jul 09, 2006 11:10 am     Reply with quote

Ah I see !

The last method is more readable, but thats just because I am not used
to the original method with the extra bit shifting etc. I will try both
methods and see if there is much of a difference in the size of the code.

Thanks very much for your help. Its difficult to find resources on how
to do this type of coding. I appreciate the time you took to explain
it.

Best regards Steve.
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