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 CCS Technical Support

Pointer Assistance

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



Joined: 16 Jan 2005
Posts: 559
Location: Tucson, AZ

View user's profile Send private message

Pointer Assistance
PostPosted: Wed Mar 14, 2007 11:36 am     Reply with quote

Hello All,

I'm trying to write a driver for the FM25L256. I would like to take advantage of the ability to sequentially write and read from the part. I'm using UNITRANT's I2C code as a go-by, but I would like to be able to read and write int16's. Could somebody give me a reading on the following and see if it makes sense. This is what I'd like to do....

Pass the starting address where the data is to be written, a pointer to where the data is to come from, and the total number of bytes to be written.

Can I pass the function a pointer to an array of int16 values and just double the count? In other words, the total number of bytes to be written would be 2 * the total int16 values in the array.

So really the pointer that is passed is just the address of the first byte of the array, I can do anything I want after that with pointer math?


Code:

void write_seq_fram(int16 start_addr, int8 *pntr, int16 count)
{
   if(start_addr + count <= FRAM_SIZE)
   {
      setup_spi(SPI_MASTER | SPI_MODE_0_0 | SPI_CLK_DIV_1);
      output_low(FRAM_CS);       //select FRAM
      spi_write(WREN);           //enable writes, required prior to WRITE cmd
      output_high(FRAM_CS);      //de-select FRAM, required between each op-code
      delay_cycles(1);           //ensure compiler doesn't remove the pin toggle
      output_low(FRAM_CS);       //re-select the FRAM
      spi_write(WRITE);          // send the WRITE op-code
      spi_write(start_addr>>8);  //send the high byte of the address
      spi_write(start_addr);     //send the low byte of the address
      do
      {
         //restart_wdt();        //uncomment if slow speeds
         spi_write(*pntr++);
      } while(--count);
      output_high(FRAM_CS);      //de-select FRAM
   }
}



Thanks,

John
jecottrell



Joined: 16 Jan 2005
Posts: 559
Location: Tucson, AZ

View user's profile Send private message

PostPosted: Wed Mar 14, 2007 6:34 pm     Reply with quote

OK. So I'm trying to blunder my way through this and my understanding of pointers is causing major headaches. I have the following test function that I can get to work just fine in one circumstance, but when I use pointers in one part of it I get an odd result....

Code:

void fram_test(void)
{

   int16 i;
   int8 result[256];
   
   int8 *pntr = result;

   int16 start_addr = 0;

   //preload the array to write to FRAM   
   for(i = 0; i < 256; i++)
   {
      result[i] = i;
   }

   setup_spi(SPI_MASTER | SPI_MODE_0_0 | SPI_CLK_DIV_4);
   fprintf(XBEE,"SPI set-up complete\n\r");
   
   output_low(FRAM_CS);       //select FRAM
   spi_write(WREN);           //enable writes, required prior to WRITE cmd
   output_high(FRAM_CS);      //de-select FRAM, required between each op-code
   fprintf(XBEE,"FRAM WREN complete\n\r");


   output_low(FRAM_CS);       //re-select the FRAM
   spi_write(WRITE);          // send the WRITE op-code
   spi_write(start_addr>>8);  //send the high byte of the address
   spi_write(start_addr);     //send the low byte of the address
   for(i = 0; i < 256; i++)
   {
      spi_write(*pntr++);
   }
   output_high(FRAM_CS);      //de-select FRAM

   fprintf(XBEE,"FRAM write complete\n\r");
   
   //clear the holding array prior to reading from FRAM
   for(i = 0; i < 256; i++)
   {
      result[i] = 0;
   }

   output_low(FRAM_CS);       //re-select the FRAM
   spi_write(READ);          // send the WRITE op-code
   spi_write(start_addr>>8);  //send the high byte of the address
   spi_write(start_addr);     //send the low byte of the address
   
   //read from FRAM and put in holding array
   for(i = 0; i < 256; i++)
   {
      *pntr++ = spi_read(0);     //ODD OUTPUT, SEE BELOW
      //result[i] = spi_read(0);   //This one Works!
   }
   output_high(FRAM_CS);      //de-select FRAM

   for(i = 0; i < 255; i++)
   {
      fprintf(XBEE,"%u\n\r", result[i]);
   }
}



The odd output is this....
Code:

0
0
.
.   (I suspect 129 or so zeroes?)
.
0
0
1
2
3
.
.   (sequential from 0 to 126)
.
125
126


Any help or pointers would be greatly appreciated,

John
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Mar 14, 2007 7:00 pm     Reply with quote

You're using 'pntr' in two places in your routine, but you only
initialize it at the start of the routine. It's not initialized prior
to the 2nd usage.
jecottrell



Joined: 16 Jan 2005
Posts: 559
Location: Tucson, AZ

View user's profile Send private message

PostPosted: Wed Mar 14, 2007 7:23 pm     Reply with quote

PCM,

Thanks for looking. I caught that and i is an int16. I've fixed both of those but still get the same result. I re-initialize pntr before I re-use it with:

Code:

*pntr = result;


But I still get the same results.

When I changed i to an int8 I also changed all of the for loops to i < 255 so they wouldn't infinite loop.

Any other ideas?

Thanks for the help, I'm running out of places to look.

John
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Mar 14, 2007 7:29 pm     Reply with quote

That's not correct.
To set the pointer to the address of the array, you do this:
Code:
pntr = result;


In my opinion, it's better not to initialize pointers in the declaration
statement. Do it with an explicit line of code, every time you're
going to use the pointer. Then you won't run into this type of problem.
jecottrell



Joined: 16 Jan 2005
Posts: 559
Location: Tucson, AZ

View user's profile Send private message

PostPosted: Wed Mar 14, 2007 7:38 pm     Reply with quote

Arghhhhhhhh....

OK. It works when I do that. But why, when you initialize pntr is it done with the *?

I think I just figured it out as I was typing the question. In the

Code:

int8 *pntr = result;


statement, the * is actually part of the declaration, not the initialization?

So the correct way to break that line into two lines would be to...

Code:

int8 *pntr;
pntr = result;


No?

Thanks for helping with something that should have been obvious.

John
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Mar 14, 2007 8:12 pm     Reply with quote

The '*' has two meanings. When it's used in a declaration, it means
that you're declaring a pointer. When it's used in a statement, it
means to access the contents of the address pointed to by the pointer.
Or, in C jargon, it means to "dereference" the pointer.

You can initialize the pointer in the declaration in the way that you
did it. It's just that for me, I don't think it's a safe way to do it,
in terms of being careful in your coding practices. In other words,
because you had the initialization up in the declarations, you overlooked
that it had to be initialized again later in the code. If you had explicitly
initialized it in the code (as you did in your latest post), then it would
have been more obvious that you needed to do it again for the 2nd
loop.
jecottrell



Joined: 16 Jan 2005
Posts: 559
Location: Tucson, AZ

View user's profile Send private message

PostPosted: Wed Mar 14, 2007 8:41 pm     Reply with quote

Thanks a bunch. That makes all the sense in the world.

John
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